LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-tyty.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 86.4 % 2072 1790
Test Date: 2026-02-28 14:20:25 Functions: 90.8 % 346 314
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2020-2026 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-system.h"
      20              : #include "rust-tyty.h"
      21              : #include "rust-tyty-subst.h"
      22              : #include "rust-tyty-visitor.h"
      23              : #include "rust-hir-map.h"
      24              : #include "rust-location.h"
      25              : #include "rust-type-util.h"
      26              : #include "rust-hir-type-bounds.h"
      27              : #include "rust-substitution-mapper.h"
      28              : #include "rust-hir-trait-reference.h"
      29              : #include "rust-hir-trait-resolve.h"
      30              : #include "tree-pretty-print.h"
      31              : 
      32              : #include "optional.h"
      33              : #include "options.h"
      34              : #include "tree.h"
      35              : #include "fold-const.h"
      36              : 
      37              : namespace Rust {
      38              : namespace TyTy {
      39              : 
      40              : std::string
      41        29690 : TypeKindFormat::to_string (TypeKind kind)
      42              : {
      43        29690 :   switch (kind)
      44              :     {
      45            0 :     case TypeKind::INFER:
      46            0 :       return "Infer";
      47              : 
      48            8 :     case TypeKind::ADT:
      49            8 :       return "ADT";
      50              : 
      51            0 :     case TypeKind::STR:
      52            0 :       return "STR";
      53              : 
      54            9 :     case TypeKind::REF:
      55            9 :       return "REF";
      56              : 
      57            0 :     case TypeKind::POINTER:
      58            0 :       return "POINTER";
      59              : 
      60            0 :     case TypeKind::PARAM:
      61            0 :       return "PARAM";
      62              : 
      63            2 :     case TypeKind::ARRAY:
      64            2 :       return "ARRAY";
      65              : 
      66            0 :     case TypeKind::SLICE:
      67            0 :       return "SLICE";
      68              : 
      69        29580 :     case TypeKind::FNDEF:
      70        29580 :       return "FnDef";
      71              : 
      72            0 :     case TypeKind::FNPTR:
      73            0 :       return "FnPtr";
      74              : 
      75            5 :     case TypeKind::TUPLE:
      76            5 :       return "Tuple";
      77              : 
      78            0 :     case TypeKind::BOOL:
      79            0 :       return "Bool";
      80              : 
      81            0 :     case TypeKind::CHAR:
      82            0 :       return "Char";
      83              : 
      84           24 :     case TypeKind::INT:
      85           24 :       return "Int";
      86              : 
      87            0 :     case TypeKind::UINT:
      88            0 :       return "Uint";
      89              : 
      90            0 :     case TypeKind::FLOAT:
      91            0 :       return "Float";
      92              : 
      93            2 :     case TypeKind::USIZE:
      94            2 :       return "Usize";
      95              : 
      96            0 :     case TypeKind::ISIZE:
      97            0 :       return "Isize";
      98              : 
      99            0 :     case TypeKind::NEVER:
     100            0 :       return "Never";
     101              : 
     102            0 :     case TypeKind::PLACEHOLDER:
     103            0 :       return "Placeholder";
     104              : 
     105            0 :     case TypeKind::PROJECTION:
     106            0 :       return "Projection";
     107              : 
     108            0 :     case TypeKind::DYNAMIC:
     109            0 :       return "Dynamic";
     110              : 
     111           60 :     case TypeKind::CLOSURE:
     112           60 :       return "Closure";
     113              : 
     114            0 :     case TypeKind::OPAQUE:
     115            0 :       return "Opaque";
     116              : 
     117            0 :     case TypeKind::CONST:
     118            0 :       return "Const";
     119              : 
     120            0 :     case TypeKind::ERROR:
     121            0 :       return "ERROR";
     122              :     }
     123            0 :   rust_unreachable ();
     124              : }
     125              : 
     126              : bool
     127            0 : is_primitive_type_kind (TypeKind kind)
     128              : {
     129            0 :   switch (kind)
     130              :     {
     131              :     case TypeKind::BOOL:
     132              :     case TypeKind::CHAR:
     133              :     case TypeKind::INT:
     134              :     case TypeKind::UINT:
     135              :     case TypeKind::ISIZE:
     136              :     case TypeKind::USIZE:
     137              :     case TypeKind::FLOAT:
     138              :     case TypeKind::NEVER:
     139              :     case TypeKind::STR:
     140              :       return true;
     141            0 :     default:
     142            0 :       return false;
     143              :     }
     144              : }
     145              : 
     146              : // BASE TYPE
     147              : 
     148      1512161 : BaseType::BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
     149      1512161 :                     std::set<HirId> refs)
     150      1512161 :   : TypeBoundsMappings ({}), kind (kind), ref (ref), ty_ref (ty_ref),
     151      1512161 :     orig_ref (ref), combined (refs), ident (ident),
     152      3024322 :     mappings (Analysis::Mappings::get ())
     153      1512161 : {}
     154              : 
     155     85836901 : BaseType::BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
     156              :                     std::vector<TypeBoundPredicate> specified_bounds,
     157     85836901 :                     std::set<HirId> refs)
     158     85836901 :   : TypeBoundsMappings (specified_bounds), kind (kind), ref (ref),
     159     85836901 :     ty_ref (ty_ref), orig_ref (ref), combined (refs), ident (ident),
     160    171673802 :     mappings (Analysis::Mappings::get ())
     161     85836901 : {}
     162              : 
     163        96048 : BaseType::~BaseType () {}
     164              : 
     165              : HirId
     166     98526584 : BaseType::get_ref () const
     167              : {
     168     98526584 :   return ref;
     169              : }
     170              : 
     171              : void
     172       376160 : BaseType::set_ref (HirId id)
     173              : {
     174       376160 :   if (id != ref)
     175       225790 :     append_reference (ref);
     176       376160 :   ref = id;
     177       376160 : }
     178              : 
     179              : HirId
     180     96374147 : BaseType::get_ty_ref () const
     181              : {
     182     96374147 :   return ty_ref;
     183              : }
     184              : 
     185              : void
     186       334538 : BaseType::set_ty_ref (HirId id)
     187              : {
     188       334538 :   ty_ref = id;
     189       334538 : }
     190              : HirId
     191         6712 : BaseType::get_orig_ref () const
     192              : {
     193         6712 :   return orig_ref;
     194              : }
     195              : 
     196              : bool
     197       254889 : BaseType::is_equal (const BaseType &other) const
     198              : {
     199       254889 :   return get_kind () == other.get_kind ();
     200              : }
     201              : 
     202              : bool
     203       777967 : BaseType::is_unit () const
     204              : {
     205       777967 :   const TyTy::BaseType *x = destructure ();
     206       777967 :   switch (x->get_kind ())
     207              :     {
     208              :     case PARAM:
     209              :     case PROJECTION:
     210              :     case PLACEHOLDER:
     211              :     case FNPTR:
     212              :     case FNDEF:
     213              :     case ARRAY:
     214              :     case SLICE:
     215              :     case POINTER:
     216              :     case REF:
     217              :     case CLOSURE:
     218              :     case INFER:
     219              :     case BOOL:
     220              :     case CHAR:
     221              :     case INT:
     222              :     case UINT:
     223              :     case FLOAT:
     224              :     case USIZE:
     225              :     case ISIZE:
     226              :     case OPAQUE:
     227              :     case STR:
     228              :     case DYNAMIC:
     229              :     case CONST:
     230              :     case ERROR:
     231              :       return false;
     232              : 
     233              :       // FIXME ! is coerceable to () so we need to fix that
     234              :     case NEVER:
     235              :       return true;
     236              : 
     237        10742 :     case TUPLE:
     238        10742 :       {
     239        10742 :         return x->as<const TupleType> ()->num_fields () == 0;
     240              :       }
     241              : 
     242       740581 :     case ADT:
     243       740581 :       {
     244       740581 :         auto adt = x->as<const ADTType> ();
     245       740581 :         if (adt->is_enum ())
     246              :           return false;
     247              : 
     248       775342 :         for (const auto &variant : adt->get_variants ())
     249              :           {
     250       639996 :             if (variant->num_fields () > 0)
     251       631852 :               return false;
     252              :           }
     253              : 
     254              :         return true;
     255              :       }
     256              :     }
     257              :   return false;
     258              : }
     259              : 
     260              : TypeKind
     261    197153688 : BaseType::get_kind () const
     262              : {
     263    197153688 :   return kind;
     264              : }
     265              : 
     266              : std::set<HirId>
     267     87300219 : BaseType::get_combined_refs () const
     268              : {
     269     87300219 :   return combined;
     270              : }
     271              : 
     272              : void
     273      3232728 : BaseType::append_reference (HirId id)
     274              : {
     275      3232728 :   combined.insert (id);
     276      3232728 : }
     277              : 
     278              : const RustIdent &
     279        85718 : BaseType::get_ident () const
     280              : {
     281        85718 :   return ident;
     282              : }
     283              : 
     284              : location_t
     285        34635 : BaseType::get_locus () const
     286              : {
     287        34635 :   return ident.locus;
     288              : }
     289              : 
     290              : // FIXME this is missing locus
     291              : bool
     292        76801 : BaseType::satisfies_bound (const TypeBoundPredicate &predicate, bool emit_error)
     293              : {
     294        76801 :   const Resolver::TraitReference *query = predicate.get ();
     295        83033 :   for (const auto &bound : specified_bounds)
     296              :     {
     297        28280 :       const Resolver::TraitReference *item = bound.get ();
     298        28280 :       if (item->satisfies_bound (*query))
     299        22771 :         return true;
     300              :     }
     301              : 
     302        54753 :   if (destructure ()->is<InferType> ())
     303              :     return true;
     304              : 
     305        54030 :   bool satisfied = false;
     306        54030 :   auto probed = Resolver::TypeBoundsProbe::Probe (this);
     307       138863 :   for (const auto &b : probed)
     308              :     {
     309       130989 :       const Resolver::TraitReference *bound = b.first;
     310       130989 :       if (bound->satisfies_bound (*query))
     311              :         {
     312              :           satisfied = true;
     313              :           break;
     314              :         }
     315              :     }
     316              : 
     317        54030 :   if (!satisfied)
     318              :     return false;
     319              : 
     320       143438 :   for (const auto &b : probed)
     321              :     {
     322       143438 :       const Resolver::TraitReference *bound = b.first;
     323       143438 :       if (!bound->is_equal (*query))
     324        97282 :         continue;
     325              : 
     326              :       // builtin ones have no impl-block this needs fixed and use a builtin node
     327              :       // of somekind
     328        46156 :       if (b.second == nullptr)
     329              :         return true;
     330              : 
     331              :       // need to check that associated types can match as well
     332        46156 :       const HIR::ImplBlock &impl = *(b.second);
     333       112256 :       for (const auto &item : impl.get_impl_items ())
     334              :         {
     335        66414 :           bool is_associated_type = item->get_impl_item_type ()
     336        66414 :                                     == HIR::ImplItem::ImplItemType::TYPE_ALIAS;
     337        66414 :           if (!is_associated_type)
     338        51094 :             continue;
     339              : 
     340        15320 :           TyTy::BaseType *impl_item_ty = nullptr;
     341        15320 :           Analysis::NodeMapping i = item->get_impl_mappings ();
     342        15320 :           bool query_ok = Resolver::query_type (i.get_hirid (), &impl_item_ty);
     343        15320 :           if (!query_ok)
     344          314 :             return false;
     345              : 
     346        15320 :           std::string item_name = item->get_impl_item_name ();
     347        15320 :           tl::optional<TypeBoundPredicateItem> lookup
     348        15320 :             = predicate.lookup_associated_item (item_name);
     349        15320 :           if (!lookup.has_value ())
     350              :             return false;
     351              : 
     352        15320 :           const auto *item_ref = lookup->get_raw_item ();
     353        15320 :           TyTy::BaseType *bound_ty = item_ref->get_tyty ();
     354              : 
     355        30640 :           if (!Resolver::types_compatable (
     356        15320 :                 TyTy::TyWithLocation (bound_ty, predicate.get_locus ()),
     357        15320 :                 TyTy::TyWithLocation (impl_item_ty, item->get_locus ()),
     358        15320 :                 mappings.lookup_location (get_ref ()), false /*emit-error*/,
     359              :                 false /*check-bounds*/))
     360              :             return false;
     361        15320 :         }
     362              : 
     363              :       return true;
     364              :     }
     365              : 
     366              :   return false;
     367        54030 : }
     368              : 
     369              : bool
     370        70398 : BaseType::bounds_compatible (BaseType &other, location_t locus, bool emit_error)
     371              : {
     372        70398 :   std::vector<std::reference_wrapper<const TypeBoundPredicate>>
     373        70398 :     unsatisfied_bounds;
     374       147199 :   for (auto &bound : get_specified_bounds ())
     375              :     {
     376        76801 :       if (!other.satisfies_bound (bound, emit_error))
     377         8188 :         unsatisfied_bounds.push_back (bound);
     378              :     }
     379              : 
     380              :   // lets emit a single error for this
     381        70398 :   if (unsatisfied_bounds.size () > 0)
     382              :     {
     383         6836 :       rich_location r (line_table, locus);
     384         6836 :       std::string missing_preds;
     385        15024 :       for (size_t i = 0; i < unsatisfied_bounds.size (); i++)
     386              :         {
     387         8188 :           const TypeBoundPredicate &pred = unsatisfied_bounds.at (i);
     388         8188 :           r.add_range (pred.get_locus ());
     389        16376 :           missing_preds += pred.get_name ();
     390              : 
     391         8188 :           bool have_next = (i + 1) < unsatisfied_bounds.size ();
     392         8188 :           if (have_next)
     393         1352 :             missing_preds += ", ";
     394              :         }
     395              : 
     396         6836 :       if (emit_error)
     397              :         {
     398           14 :           rust_error_at (r, ErrorCode::E0277,
     399              :                          "bounds not satisfied for %s %qs is not satisfied",
     400           28 :                          other.get_name ().c_str (), missing_preds.c_str ());
     401              :           // rust_assert (!emit_error);
     402              :         }
     403         6836 :     }
     404              : 
     405        70398 :   return unsatisfied_bounds.size () == 0;
     406        70398 : }
     407              : 
     408              : void
     409        12107 : BaseType::inherit_bounds (const BaseType &other)
     410              : {
     411        12107 :   inherit_bounds (other.get_specified_bounds ());
     412        12107 : }
     413              : 
     414              : void
     415        61147 : BaseType::inherit_bounds (
     416              :   const std::vector<TyTy::TypeBoundPredicate> &specified_bounds)
     417              : {
     418       121125 :   for (auto &bound : specified_bounds)
     419              :     {
     420        59978 :       add_bound (bound);
     421              :     }
     422        61147 : }
     423              : 
     424              : BaseType *
     425        11169 : BaseType::get_root ()
     426              : {
     427        13140 :   TyTy::BaseType *root = this;
     428              : 
     429        13140 :   if (const auto r = root->try_as<const ReferenceType> ())
     430              :     {
     431         1467 :       root = r->get_base ()->get_root ();
     432              :     }
     433        11673 :   else if (const auto r = root->try_as<const PointerType> ())
     434              :     {
     435          284 :       root = r->get_base ()->get_root ();
     436              :     }
     437              :   // these are an unsize
     438        11389 :   else if (const auto r = root->try_as<const SliceType> ())
     439              :     {
     440          220 :       root = r->get_element_type ()->get_root ();
     441              :     }
     442              :   //  else if (const auto r = root->try_as<const ArrayType> ())
     443              :   //    {
     444              :   //      root = r->get_element_type ()->get_root ();
     445              :   //    }
     446              : 
     447        11169 :   return root;
     448              : }
     449              : 
     450              : BaseType *
     451      5161777 : BaseType::destructure ()
     452              : {
     453      5161777 :   int recurisve_ops = 0;
     454      5161777 :   BaseType *x = this;
     455      5403617 :   while (true)
     456              :     {
     457      5403617 :       if (recurisve_ops++ >= rust_max_recursion_depth)
     458              :         {
     459            0 :           rust_error_at (
     460              :             UNDEF_LOCATION,
     461              :             "%<recursion depth%> count exceeds limit of %i (use "
     462              :             "%<frust-max-recursion-depth=%> to increase the limit)",
     463              :             rust_max_recursion_depth);
     464            0 :           return new ErrorType (get_ref ());
     465              :         }
     466              : 
     467      5403617 :       if (auto p = x->try_as<ParamType> ())
     468              :         {
     469       363724 :           auto pr = p->resolve ();
     470       363724 :           if (pr == x)
     471              :             return pr;
     472              : 
     473              :           x = pr;
     474              :         }
     475      5039893 :       else if (x->get_kind () == TypeKind::CONST)
     476              :         {
     477         7316 :           auto p = x->as_const_type ();
     478         7316 :           if (p->const_kind () == BaseConstType::ConstKind::Decl)
     479              :             {
     480          741 :               auto decl = static_cast<ConstParamType *> (p);
     481          741 :               auto pr = decl->resolve ();
     482          741 :               if (pr == x)
     483              :                 return pr;
     484              : 
     485              :               x = pr;
     486              :             }
     487              :           else
     488              :             {
     489              :               return x;
     490              :             }
     491              :         }
     492      5032577 :       else if (auto p = x->try_as<PlaceholderType> ())
     493              :         {
     494        22326 :           if (!p->can_resolve ())
     495              :             return p;
     496              : 
     497         6313 :           x = p->resolve ();
     498              :         }
     499      5010251 :       else if (auto p = x->try_as<ProjectionType> ())
     500              :         {
     501        20503 :           x = p->get ();
     502              :         }
     503              :       else
     504              :         {
     505              :           return x;
     506              :         }
     507              :     }
     508              : 
     509              :   return x;
     510              : }
     511              : 
     512              : const BaseType *
     513      7985602 : BaseType::destructure () const
     514              : {
     515      7985602 :   int recurisve_ops = 0;
     516      7985602 :   const BaseType *x = this;
     517      9013543 :   while (true)
     518              :     {
     519      9013543 :       if (recurisve_ops++ >= rust_max_recursion_depth)
     520              :         {
     521            0 :           rust_error_at (
     522              :             UNDEF_LOCATION,
     523              :             "%<recursion depth%> count exceeds limit of %i (use "
     524              :             "%<frust-max-recursion-depth=%> to increase the limit)",
     525              :             rust_max_recursion_depth);
     526            0 :           return new ErrorType (get_ref ());
     527              :         }
     528              : 
     529      9013543 :       if (auto p = x->try_as<const ParamType> ())
     530              :         {
     531      1679333 :           auto pr = p->resolve ();
     532      1679333 :           if (pr == x)
     533              :             return pr;
     534              : 
     535              :           x = pr;
     536              :         }
     537      7334210 :       else if (x->get_kind () == TypeKind::CONST)
     538              :         {
     539        18663 :           auto p = x->as_const_type ();
     540        18663 :           if (p->const_kind () == BaseConstType::ConstKind::Decl)
     541              :             {
     542         1386 :               auto decl = static_cast<const ConstParamType *> (p);
     543         1386 :               auto pr = decl->resolve ();
     544         1386 :               if (pr == x)
     545              :                 return pr;
     546              : 
     547              :               x = pr;
     548              :             }
     549              :           else
     550              :             {
     551              :               return x;
     552              :             }
     553              :         }
     554      7315547 :       else if (auto p = x->try_as<const PlaceholderType> ())
     555              :         {
     556        20689 :           if (!p->can_resolve ())
     557              :             return p;
     558              : 
     559         3948 :           x = p->resolve ();
     560              :         }
     561      7294858 :       else if (auto p = x->try_as<const ProjectionType> ())
     562              :         {
     563         4661 :           x = p->get ();
     564              :         }
     565      7290197 :       else if (auto p = x->try_as<const OpaqueType> ())
     566              :         {
     567          254 :           auto pr = p->resolve ();
     568          254 :           if (pr == x)
     569              :             return pr;
     570              : 
     571              :           x = pr;
     572              :         }
     573              :       else
     574              :         {
     575              :           return x;
     576              :         }
     577              :     }
     578              : 
     579              :   return x;
     580              : }
     581              : 
     582              : BaseType *
     583        17444 : BaseType::monomorphized_clone () const
     584              : {
     585        17444 :   const TyTy::BaseType *x = destructure ();
     586              : 
     587        17444 :   if (auto arr = x->try_as<const ArrayType> ())
     588              :     {
     589           80 :       TyVar elm = arr->get_var_element_type ().monomorphized_clone ();
     590          160 :       return new ArrayType (arr->get_ref (), arr->get_ty_ref (), ident.locus,
     591           80 :                             arr->get_capacity_var (), elm,
     592           80 :                             arr->get_combined_refs ());
     593              :     }
     594        17364 :   else if (auto slice = x->try_as<const SliceType> ())
     595              :     {
     596          161 :       TyVar elm = slice->get_var_element_type ().monomorphized_clone ();
     597          161 :       return new SliceType (slice->get_ref (), slice->get_ty_ref (),
     598          161 :                             ident.locus, elm, slice->get_combined_refs ());
     599              :     }
     600        17203 :   else if (auto ptr = x->try_as<const PointerType> ())
     601              :     {
     602          653 :       TyVar elm = ptr->get_var_element_type ().monomorphized_clone ();
     603          653 :       return new PointerType (ptr->get_ref (), ptr->get_ty_ref (), elm,
     604          653 :                               ptr->mutability (), ptr->get_combined_refs ());
     605              :     }
     606        16550 :   else if (auto ref = x->try_as<const ReferenceType> ())
     607              :     {
     608          279 :       TyVar elm = ref->get_var_element_type ().monomorphized_clone ();
     609          279 :       return new ReferenceType (ref->get_ref (), ref->get_ty_ref (), elm,
     610          558 :                                 ref->mutability (), ref->get_region (),
     611          837 :                                 ref->get_combined_refs ());
     612              :     }
     613        16271 :   else if (auto tuple = x->try_as<const TupleType> ())
     614              :     {
     615         4605 :       std::vector<TyVar> cloned_fields;
     616         5269 :       for (const auto &f : tuple->get_fields ())
     617          664 :         cloned_fields.push_back (f.monomorphized_clone ());
     618              : 
     619         4605 :       return new TupleType (tuple->get_ref (), tuple->get_ty_ref (),
     620         4605 :                             ident.locus, cloned_fields,
     621         4605 :                             tuple->get_combined_refs ());
     622         4605 :     }
     623        11666 :   else if (auto fn = x->try_as<const FnType> ())
     624              :     {
     625            0 :       std::vector<TyTy::FnParam> cloned_params;
     626            0 :       for (auto &p : fn->get_params ())
     627            0 :         cloned_params.push_back (p.monomorphized_clone ());
     628              : 
     629            0 :       BaseType *retty = fn->get_return_type ()->monomorphized_clone ();
     630            0 :       return new FnType (fn->get_ref (), fn->get_ty_ref (), fn->get_id (),
     631            0 :                          fn->get_identifier (), fn->ident, fn->get_flags (),
     632              :                          fn->get_abi (), std::move (cloned_params), retty,
     633            0 :                          fn->clone_substs (), fn->get_substitution_arguments (),
     634              :                          fn->get_region_constraints (),
     635            0 :                          fn->get_combined_refs ());
     636            0 :     }
     637        11666 :   else if (auto fn = x->try_as<const FnPtr> ())
     638              :     {
     639            0 :       std::vector<TyVar> cloned_params;
     640            0 :       for (auto &p : fn->get_params ())
     641            0 :         cloned_params.push_back (p.monomorphized_clone ());
     642              : 
     643            0 :       TyVar retty = fn->get_var_return_type ().monomorphized_clone ();
     644            0 :       return new FnPtr (fn->get_ref (), fn->get_ty_ref (), ident.locus,
     645              :                         std::move (cloned_params), retty, fn->get_abi (),
     646            0 :                         fn->get_unsafety (), fn->get_combined_refs ());
     647            0 :     }
     648        11666 :   else if (auto adt = x->try_as<const ADTType> ())
     649              :     {
     650         2102 :       std::vector<VariantDef *> cloned_variants;
     651         6261 :       for (auto &variant : adt->get_variants ())
     652         4159 :         cloned_variants.push_back (variant->monomorphized_clone ());
     653              : 
     654         2102 :       return new ADTType (adt->get_id (), adt->get_ref (), adt->get_ty_ref (),
     655         4204 :                           adt->get_identifier (), adt->ident,
     656              :                           adt->get_adt_kind (), cloned_variants,
     657         2102 :                           adt->clone_substs (), adt->get_repr_options (),
     658              :                           adt->get_used_arguments (),
     659              :                           adt->get_region_constraints (),
     660         8408 :                           adt->get_combined_refs ());
     661         2102 :     }
     662              :   else
     663              :     {
     664         9564 :       return x->clone ();
     665              :     }
     666              : 
     667              :   rust_unreachable ();
     668              :   return nullptr;
     669              : }
     670              : 
     671              : std::string
     672        29690 : BaseType::mappings_str () const
     673              : {
     674        59380 :   std::string buffer = "Ref: " + std::to_string (get_ref ())
     675        89070 :                        + " TyRef: " + std::to_string (get_ty_ref ());
     676        29690 :   buffer += "[";
     677        43850 :   for (auto &ref : combined)
     678        42480 :     buffer += std::to_string (ref) + ",";
     679        29690 :   buffer += "]";
     680        59380 :   return "(" + buffer + ")";
     681        29690 : }
     682              : 
     683              : std::string
     684     13283196 : BaseType::debug_str () const
     685              : {
     686              :   // return TypeKindFormat::to_string (get_kind ()) + ":" + as_string () + ":"
     687              :   //        + mappings_str () + ":" + bounds_as_string ();
     688     13283196 :   return get_name ();
     689              : }
     690              : 
     691              : void
     692          540 : BaseType::debug () const
     693              : {
     694          540 :   rust_debug ("[%p] %s", static_cast<const void *> (this),
     695              :               debug_str ().c_str ());
     696          540 : }
     697              : 
     698              : const TyTy::BaseType *
     699         6437 : BaseType::contains_infer () const
     700              : {
     701         6614 :   const TyTy::BaseType *x = destructure ();
     702              : 
     703         6614 :   if (auto fn = x->try_as<const FnType> ())
     704              :     {
     705            0 :       for (const auto &param : fn->get_params ())
     706              :         {
     707            0 :           auto infer = param.get_type ()->contains_infer ();
     708            0 :           if (infer)
     709         6437 :             return infer;
     710              :         }
     711            0 :       return fn->get_return_type ()->contains_infer ();
     712              :     }
     713         6614 :   else if (auto fn = x->try_as<const FnPtr> ())
     714              :     {
     715            0 :       for (const auto &param : fn->get_params ())
     716              :         {
     717            0 :           auto infer = param.get_tyty ()->contains_infer ();
     718            0 :           if (infer)
     719         6437 :             return infer;
     720              :         }
     721            0 :       return fn->get_return_type ()->contains_infer ();
     722              :     }
     723         6614 :   else if (auto adt = x->try_as<const ADTType> ())
     724              :     {
     725          231 :       for (auto &variant : adt->get_variants ())
     726              :         {
     727          141 :           bool is_num_variant
     728          141 :             = variant->get_variant_type () == VariantDef::VariantType::NUM;
     729          141 :           if (is_num_variant)
     730           58 :             continue;
     731              : 
     732          175 :           for (auto &field : variant->get_fields ())
     733              :             {
     734           93 :               const BaseType *field_type = field->get_field_type ();
     735           93 :               auto infer = (field_type->contains_infer ());
     736           93 :               if (infer)
     737         6437 :                 return infer;
     738              :             }
     739              :         }
     740              :       return nullptr;
     741              :     }
     742         6523 :   else if (auto arr = x->try_as<const ArrayType> ())
     743              :     {
     744           32 :       return arr->get_element_type ()->contains_infer ();
     745              :     }
     746         6491 :   else if (auto slice = x->try_as<const SliceType> ())
     747              :     {
     748           49 :       return slice->get_element_type ()->contains_infer ();
     749              :     }
     750         6442 :   else if (auto ptr = x->try_as<const PointerType> ())
     751              :     {
     752           49 :       return ptr->get_base ()->contains_infer ();
     753              :     }
     754         6393 :   else if (auto ref = x->try_as<const ReferenceType> ())
     755              :     {
     756           47 :       return ref->get_base ()->contains_infer ();
     757              :     }
     758         6346 :   else if (auto tuple = x->try_as<const TupleType> ())
     759              :     {
     760         3273 :       for (size_t i = 0; i < tuple->num_fields (); i++)
     761              :         {
     762           18 :           auto infer = (tuple->get_field (i)->contains_infer ());
     763           18 :           if (infer)
     764              :             return infer;
     765              :         }
     766              :       return nullptr;
     767              :     }
     768         3091 :   else if (auto closure = x->try_as<const ClosureType> ())
     769              :     {
     770            0 :       auto infer = (closure->get_parameters ().contains_infer ());
     771            0 :       if (infer)
     772              :         return infer;
     773            0 :       return closure->get_result_type ().contains_infer ();
     774              :     }
     775         3091 :   else if (x->is<InferType> ())
     776              :     {
     777              :       return x;
     778              :     }
     779              : 
     780              :   return nullptr;
     781              : }
     782              : 
     783              : bool
     784      5688959 : BaseType::is_concrete () const
     785              : {
     786      5940663 :   const TyTy::BaseType *x = destructure ();
     787              : 
     788     11587772 :   if (x->is<ParamType> () || x->is<ProjectionType> ())
     789              :     {
     790       293554 :       return false;
     791              :     }
     792      5647109 :   else if (x->get_kind () == TyTy::TypeKind::CONST)
     793              :     {
     794        17984 :       auto p = x->as_const_type ();
     795        17984 :       if (p->const_kind () == BaseConstType::ConstKind::Decl)
     796              :         return false;
     797              : 
     798              :       return true;
     799              :     }
     800              :   // placeholder is a special case for this case when it is not resolvable
     801              :   // it means we its just an empty placeholder associated type which is
     802              :   // concrete
     803      5629125 :   else if (x->is<PlaceholderType> ())
     804              :     {
     805              :       return true;
     806              :     }
     807      5613097 :   else if (auto fn = x->try_as<const FnType> ())
     808              :     {
     809        19360 :       for (const auto &param : fn->get_params ())
     810              :         {
     811        12404 :           if (!param.get_type ()->is_concrete ())
     812       339293 :             return false;
     813              :         }
     814         6956 :       return fn->get_return_type ()->is_concrete ();
     815              :     }
     816      5604733 :   else if (auto fn = x->try_as<const FnPtr> ())
     817              :     {
     818         4276 :       for (const auto &param : fn->get_params ())
     819              :         {
     820           95 :           if (!param.get_tyty ()->is_concrete ())
     821       339293 :             return false;
     822              :         }
     823         4181 :       return fn->get_return_type ()->is_concrete ();
     824              :     }
     825      5600548 :   else if (auto adt = x->try_as<const ADTType> ())
     826              :     {
     827       655732 :       if (adt->is_unit ())
     828       116878 :         return !adt->needs_substitution ();
     829              : 
     830      1179143 :       for (auto &variant : adt->get_variants ())
     831              :         {
     832       683266 :           bool is_num_variant
     833       683266 :             = variant->get_variant_type () == VariantDef::VariantType::NUM;
     834       683266 :           if (is_num_variant)
     835       137768 :             continue;
     836              : 
     837      1804764 :           for (auto &field : variant->get_fields ())
     838              :             {
     839      1302243 :               const BaseType *field_type = field->get_field_type ();
     840      1302243 :               if (!field_type->is_concrete ())
     841       339293 :                 return false;
     842              :             }
     843              :         }
     844              :       return true;
     845              :     }
     846      4944816 :   else if (auto arr = x->try_as<const ArrayType> ())
     847              :     {
     848        14971 :       return arr->get_element_type ()->is_concrete ()
     849        14971 :              && arr->get_capacity ()->is_concrete ();
     850              :     }
     851      4929845 :   else if (auto slice = x->try_as<const SliceType> ())
     852              :     {
     853        12688 :       return slice->get_element_type ()->is_concrete ();
     854              :     }
     855      4917157 :   else if (auto ptr = x->try_as<const PointerType> ())
     856              :     {
     857        17885 :       return ptr->get_base ()->is_concrete ();
     858              :     }
     859      4899272 :   else if (auto ref = x->try_as<const ReferenceType> ())
     860              :     {
     861       209994 :       return ref->get_base ()->is_concrete ();
     862              :     }
     863      4689278 :   else if (auto tuple = x->try_as<const TupleType> ())
     864              :     {
     865        18943 :       for (size_t i = 0; i < tuple->num_fields (); i++)
     866              :         {
     867         2642 :           if (!tuple->get_field (i)->is_concrete ())
     868              :             return false;
     869              :         }
     870              :       return true;
     871              :     }
     872      4672672 :   else if (auto closure = x->try_as<const ClosureType> ())
     873              :     {
     874          259 :       if (closure->get_parameters ().is_concrete ())
     875              :         return false;
     876            0 :       return closure->get_result_type ().is_concrete ();
     877              :     }
     878     13834430 :   else if (x->is<InferType> () || x->is<BoolType> () || x->is<CharType> ()
     879      8823331 :            || x->is<IntType> () || x->is<UintType> () || x->is<FloatType> ()
     880      1185708 :            || x->is<USizeType> () || x->is<ISizeType> () || x->is<NeverType> ()
     881        32552 :            || x->is<StrType> () || x->is<DynamicObjectType> ()
     882      4672420 :            || x->is<ErrorType> ())
     883              :     {
     884      4672413 :       return true;
     885              :     }
     886              : 
     887              :   return false;
     888              : }
     889              : 
     890              : bool
     891       205386 : BaseType::has_substitutions_defined () const
     892              : {
     893       205386 :   const auto x = this;
     894       205386 :   switch (x->get_kind ())
     895              :     {
     896              :     case INFER:
     897              :     case BOOL:
     898              :     case CHAR:
     899              :     case INT:
     900              :     case UINT:
     901              :     case FLOAT:
     902              :     case USIZE:
     903              :     case ISIZE:
     904              :     case NEVER:
     905              :     case STR:
     906              :     case DYNAMIC:
     907              :     case ERROR:
     908              :     case FNPTR:
     909              :     case ARRAY:
     910              :     case SLICE:
     911              :     case POINTER:
     912              :     case REF:
     913              :     case TUPLE:
     914              :     case PARAM:
     915              :     case PLACEHOLDER:
     916              :     case CONST:
     917              :     case OPAQUE:
     918              :       return false;
     919              : 
     920            7 :     case PROJECTION:
     921            7 :       {
     922            7 :         const ProjectionType &p = *static_cast<const ProjectionType *> (x);
     923            7 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (p);
     924            7 :         return ref.has_substitutions ();
     925              :       }
     926        72040 :       break;
     927              : 
     928        72040 :     case FNDEF:
     929        72040 :       {
     930        72040 :         const FnType &fn = *static_cast<const FnType *> (x);
     931        72040 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (fn);
     932        72040 :         return ref.has_substitutions ();
     933              :       }
     934       112525 :       break;
     935              : 
     936       112525 :     case ADT:
     937       112525 :       {
     938       112525 :         const ADTType &adt = *static_cast<const ADTType *> (x);
     939       112525 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (adt);
     940       112525 :         return ref.has_substitutions ();
     941              :       }
     942            0 :       break;
     943              : 
     944            0 :     case CLOSURE:
     945            0 :       {
     946            0 :         const ClosureType &closure = *static_cast<const ClosureType *> (x);
     947            0 :         const SubstitutionRef &ref
     948              :           = static_cast<const SubstitutionRef &> (closure);
     949            0 :         return ref.has_substitutions ();
     950              :       }
     951              :       break;
     952              :     }
     953              : 
     954              :   return false;
     955              : }
     956              : 
     957              : bool
     958       117368 : BaseType::needs_generic_substitutions () const
     959              : {
     960       117368 :   const TyTy::BaseType *x = destructure ();
     961       117368 :   switch (x->get_kind ())
     962              :     {
     963              :     case INFER:
     964              :     case BOOL:
     965              :     case CHAR:
     966              :     case INT:
     967              :     case UINT:
     968              :     case FLOAT:
     969              :     case USIZE:
     970              :     case ISIZE:
     971              :     case NEVER:
     972              :     case STR:
     973              :     case DYNAMIC:
     974              :     case ERROR:
     975              :     case FNPTR:
     976              :     case ARRAY:
     977              :     case SLICE:
     978              :     case POINTER:
     979              :     case REF:
     980              :     case TUPLE:
     981              :     case PARAM:
     982              :     case PLACEHOLDER:
     983              :     case CONST:
     984              :     case OPAQUE:
     985              :       return false;
     986              : 
     987            0 :     case PROJECTION:
     988            0 :       {
     989            0 :         const ProjectionType &p = *static_cast<const ProjectionType *> (x);
     990            0 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (p);
     991            0 :         return ref.needs_substitution ();
     992              :       }
     993        13480 :       break;
     994              : 
     995        13480 :     case FNDEF:
     996        13480 :       {
     997        13480 :         const FnType &fn = *static_cast<const FnType *> (x);
     998        13480 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (fn);
     999        13480 :         return ref.needs_substitution ();
    1000              :       }
    1001        25948 :       break;
    1002              : 
    1003        25948 :     case ADT:
    1004        25948 :       {
    1005        25948 :         const ADTType &adt = *static_cast<const ADTType *> (x);
    1006        25948 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (adt);
    1007        25948 :         return ref.needs_substitution ();
    1008              :       }
    1009           53 :       break;
    1010              : 
    1011           53 :     case CLOSURE:
    1012           53 :       {
    1013           53 :         const ClosureType &closure = *static_cast<const ClosureType *> (x);
    1014           53 :         const SubstitutionRef &ref
    1015              :           = static_cast<const SubstitutionRef &> (closure);
    1016           53 :         return ref.needs_substitution ();
    1017              :       }
    1018              :       break;
    1019              :     }
    1020              : 
    1021              :   return false;
    1022              : }
    1023              : 
    1024              : const SubstitutionArgumentMappings &
    1025          245 : BaseType::get_subst_argument_mappings () const
    1026              : {
    1027          453 :   static auto empty = SubstitutionArgumentMappings::empty ();
    1028          245 :   const TyTy::BaseType *x = destructure ();
    1029          245 :   switch (x->get_kind ())
    1030              :     {
    1031            0 :     case PROJECTION:
    1032            0 :       {
    1033            0 :         const auto &p = *static_cast<const ProjectionType *> (x);
    1034            0 :         const auto &ref = static_cast<const SubstitutionRef &> (p);
    1035            0 :         return ref.get_substitution_arguments ();
    1036              :       }
    1037            0 :       break;
    1038              : 
    1039            0 :     case FNDEF:
    1040            0 :       {
    1041            0 :         const auto &fn = *static_cast<const FnType *> (x);
    1042            0 :         const auto &ref = static_cast<const SubstitutionRef &> (fn);
    1043            0 :         return ref.get_substitution_arguments ();
    1044              :       }
    1045          245 :       break;
    1046              : 
    1047          245 :     case ADT:
    1048          245 :       {
    1049          245 :         const auto &adt = *static_cast<const ADTType *> (x);
    1050          245 :         const auto &ref = static_cast<const SubstitutionRef &> (adt);
    1051          245 :         return ref.get_substitution_arguments ();
    1052              :       }
    1053            0 :       break;
    1054              : 
    1055            0 :     case CLOSURE:
    1056            0 :       {
    1057            0 :         const auto &closure = *static_cast<const ClosureType *> (x);
    1058            0 :         const auto &ref = static_cast<const SubstitutionRef &> (closure);
    1059            0 :         return ref.get_substitution_arguments ();
    1060              :       }
    1061              :       break;
    1062              : 
    1063              :     default:
    1064              :       return empty;
    1065              :     }
    1066              : 
    1067              :   return empty;
    1068              : }
    1069              : 
    1070              : // InferType
    1071              : 
    1072       116507 : InferType::InferType (HirId ref, InferTypeKind infer_kind, TypeHint hint,
    1073       116507 :                       location_t locus, std::set<HirId> refs)
    1074       116507 :   : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), locus},
    1075              :               refs),
    1076       233014 :     infer_kind (infer_kind), default_hint (hint)
    1077       116507 : {}
    1078              : 
    1079            0 : InferType::InferType (HirId ref, HirId ty_ref, InferTypeKind infer_kind,
    1080            0 :                       TypeHint hint, location_t locus, std::set<HirId> refs)
    1081              :   : BaseType (ref, ty_ref, KIND,
    1082            0 :               {Resolver::CanonicalPath::create_empty (), locus}, refs),
    1083            0 :     infer_kind (infer_kind), default_hint (hint)
    1084            0 : {}
    1085              : 
    1086              : InferType::InferTypeKind
    1087       190952 : InferType::get_infer_kind () const
    1088              : {
    1089       190952 :   return infer_kind;
    1090              : }
    1091              : 
    1092              : std::string
    1093       355025 : InferType::get_name () const
    1094              : {
    1095       355025 :   return as_string ();
    1096              : }
    1097              : 
    1098              : void
    1099            0 : InferType::accept_vis (TyVisitor &vis)
    1100              : {
    1101            0 :   vis.visit (*this);
    1102            0 : }
    1103              : 
    1104              : void
    1105          568 : InferType::accept_vis (TyConstVisitor &vis) const
    1106              : {
    1107          568 :   vis.visit (*this);
    1108          568 : }
    1109              : 
    1110              : std::string
    1111       380469 : InferType::as_string () const
    1112              : {
    1113       380469 :   switch (infer_kind)
    1114              :     {
    1115       260821 :     case GENERAL:
    1116       260821 :       return "T?";
    1117       117484 :     case INTEGRAL:
    1118       117484 :       return "<integer>";
    1119         2164 :     case FLOAT:
    1120         2164 :       return "<float>";
    1121              :     }
    1122            0 :   return "<infer::error>";
    1123              : }
    1124              : 
    1125              : BaseType *
    1126         7254 : InferType::clone () const
    1127              : {
    1128              :   // clones for inference variables are special in that they _must_ exist within
    1129              :   // the type check context and we must ensure we don't loose the chain
    1130              :   // otherwise we will end up in the missing type annotations case
    1131              :   //
    1132              :   // This means we cannot simply take over the same reference we must generate a
    1133              :   // new ref just like the get_implicit_infer_var code then we can setup the
    1134              :   // chain of references accordingly to ensure we don't loose the ability to
    1135              :   // update the inference variables when we solve the type
    1136              : 
    1137         7254 :   auto &mappings = Analysis::Mappings::get ();
    1138         7254 :   auto context = Resolver::TypeCheckContext::get ();
    1139              : 
    1140         7254 :   InferType *clone
    1141              :     = new InferType (mappings.get_next_hir_id (), get_infer_kind (),
    1142         7254 :                      default_hint, get_ident ().locus, get_combined_refs ());
    1143              : 
    1144         7254 :   context->insert_type (Analysis::NodeMapping (mappings.get_current_crate (),
    1145              :                                                UNKNOWN_NODEID,
    1146              :                                                clone->get_ref (),
    1147         7254 :                                                UNKNOWN_LOCAL_DEFID),
    1148              :                         clone);
    1149         7254 :   mappings.insert_location (clone->get_ref (),
    1150              :                             mappings.lookup_location (get_ref ()));
    1151              : 
    1152              :   // setup the chain to reference this
    1153         7254 :   clone->append_reference (get_ref ());
    1154              : 
    1155         7254 :   return clone;
    1156              : }
    1157              : 
    1158              : bool
    1159         1837 : InferType::default_type (BaseType **type) const
    1160              : {
    1161         1837 :   auto context = Resolver::TypeCheckContext::get ();
    1162         1837 :   bool ok = false;
    1163              : 
    1164              :   // NOTE: Calling this error is misleading.
    1165         1837 :   if (default_hint.kind == TypeKind::ERROR)
    1166              :     {
    1167         1837 :       switch (infer_kind)
    1168              :         {
    1169              :         case GENERAL:
    1170              :           return false;
    1171              : 
    1172         1782 :         case INTEGRAL:
    1173         1782 :           {
    1174         1782 :             ok = context->lookup_builtin ("i32", type);
    1175         1782 :             rust_assert (ok);
    1176              :             return ok;
    1177              :           }
    1178              : 
    1179           43 :         case FLOAT:
    1180           43 :           {
    1181           43 :             ok = context->lookup_builtin ("f64", type);
    1182           43 :             rust_assert (ok);
    1183              :             return ok;
    1184              :           }
    1185              :         }
    1186              :       return false;
    1187              :     }
    1188              : 
    1189            0 :   switch (default_hint.kind)
    1190              :     {
    1191            0 :     case ISIZE:
    1192            0 :       ok = context->lookup_builtin ("isize", type);
    1193            0 :       rust_assert (ok);
    1194              :       return ok;
    1195              : 
    1196            0 :     case USIZE:
    1197            0 :       ok = context->lookup_builtin ("usize", type);
    1198            0 :       rust_assert (ok);
    1199              :       return ok;
    1200              : 
    1201            0 :     case INT:
    1202            0 :       switch (default_hint.szhint)
    1203              :         {
    1204            0 :         case TypeHint::SizeHint::S8:
    1205            0 :           ok = context->lookup_builtin ("i8", type);
    1206            0 :           rust_assert (ok);
    1207              :           return ok;
    1208              : 
    1209            0 :         case TypeHint::SizeHint::S16:
    1210            0 :           ok = context->lookup_builtin ("i16", type);
    1211            0 :           rust_assert (ok);
    1212              :           return ok;
    1213              : 
    1214            0 :         case TypeHint::SizeHint::S32:
    1215            0 :           ok = context->lookup_builtin ("i32", type);
    1216            0 :           rust_assert (ok);
    1217              :           return ok;
    1218              : 
    1219            0 :         case TypeHint::SizeHint::S64:
    1220            0 :           ok = context->lookup_builtin ("i64", type);
    1221            0 :           rust_assert (ok);
    1222              :           return ok;
    1223              : 
    1224            0 :         case TypeHint::SizeHint::S128:
    1225            0 :           ok = context->lookup_builtin ("i128", type);
    1226            0 :           rust_assert (ok);
    1227              :           return ok;
    1228              : 
    1229              :         default:
    1230              :           return false;
    1231              :         }
    1232            0 :       break;
    1233              : 
    1234            0 :     case UINT:
    1235            0 :       switch (default_hint.szhint)
    1236              :         {
    1237            0 :         case TypeHint::SizeHint::S8:
    1238            0 :           ok = context->lookup_builtin ("u8", type);
    1239            0 :           rust_assert (ok);
    1240              :           return ok;
    1241              : 
    1242            0 :         case TypeHint::SizeHint::S16:
    1243            0 :           ok = context->lookup_builtin ("u16", type);
    1244            0 :           rust_assert (ok);
    1245              :           return ok;
    1246              : 
    1247            0 :         case TypeHint::SizeHint::S32:
    1248            0 :           ok = context->lookup_builtin ("u32", type);
    1249            0 :           rust_assert (ok);
    1250              :           return ok;
    1251              : 
    1252            0 :         case TypeHint::SizeHint::S64:
    1253            0 :           ok = context->lookup_builtin ("u64", type);
    1254            0 :           rust_assert (ok);
    1255              :           return ok;
    1256              : 
    1257            0 :         case TypeHint::SizeHint::S128:
    1258            0 :           ok = context->lookup_builtin ("u128", type);
    1259            0 :           rust_assert (ok);
    1260              :           return ok;
    1261              : 
    1262              :         default:
    1263              :           return false;
    1264              :         }
    1265            0 :       break;
    1266              : 
    1267            0 :     case TypeKind::FLOAT:
    1268            0 :       switch (default_hint.szhint)
    1269              :         {
    1270            0 :         case TypeHint::SizeHint::S32:
    1271            0 :           ok = context->lookup_builtin ("f32", type);
    1272            0 :           rust_assert (ok);
    1273              :           return ok;
    1274              : 
    1275            0 :         case TypeHint::SizeHint::S64:
    1276            0 :           ok = context->lookup_builtin ("f64", type);
    1277            0 :           rust_assert (ok);
    1278              :           return ok;
    1279              : 
    1280              :         default:
    1281              :           return false;
    1282              :         }
    1283              :       break;
    1284              : 
    1285              :     default:
    1286              :       return false;
    1287              :     }
    1288              : 
    1289              :   return false;
    1290              : }
    1291              : 
    1292              : void
    1293         5476 : InferType::apply_primitive_type_hint (const BaseType &hint)
    1294              : {
    1295         5476 :   switch (hint.get_kind ())
    1296              :     {
    1297         1310 :     case ISIZE:
    1298         1310 :     case USIZE:
    1299         1310 :       infer_kind = INTEGRAL;
    1300         1310 :       default_hint.kind = hint.get_kind ();
    1301         1310 :       break;
    1302              : 
    1303         3390 :     case INT:
    1304         3390 :       {
    1305         3390 :         infer_kind = INTEGRAL;
    1306         3390 :         default_hint.kind = hint.get_kind ();
    1307         3390 :         default_hint.shint = TypeHint::SignedHint::SIGNED;
    1308         3390 :         switch (hint.as<const IntType> ()->get_int_kind ())
    1309              :           {
    1310           16 :           case IntType::I8:
    1311           16 :             default_hint.szhint = TypeHint::SizeHint::S8;
    1312           16 :             break;
    1313           14 :           case IntType::I16:
    1314           14 :             default_hint.szhint = TypeHint::SizeHint::S16;
    1315           14 :             break;
    1316         3332 :           case IntType::I32:
    1317         3332 :             default_hint.szhint = TypeHint::SizeHint::S32;
    1318         3332 :             break;
    1319           14 :           case IntType::I64:
    1320           14 :             default_hint.szhint = TypeHint::SizeHint::S64;
    1321           14 :             break;
    1322           14 :           case IntType::I128:
    1323           14 :             default_hint.szhint = TypeHint::SizeHint::S128;
    1324           14 :             break;
    1325              :           }
    1326              :       }
    1327              :       break;
    1328              : 
    1329          655 :     case UINT:
    1330          655 :       {
    1331          655 :         infer_kind = INTEGRAL;
    1332          655 :         default_hint.kind = hint.get_kind ();
    1333          655 :         default_hint.shint = TypeHint::SignedHint::UNSIGNED;
    1334          655 :         switch (hint.as<const UintType> ()->get_uint_kind ())
    1335              :           {
    1336          320 :           case UintType::U8:
    1337          320 :             default_hint.szhint = TypeHint::SizeHint::S8;
    1338          320 :             break;
    1339           45 :           case UintType::U16:
    1340           45 :             default_hint.szhint = TypeHint::SizeHint::S16;
    1341           45 :             break;
    1342          196 :           case UintType::U32:
    1343          196 :             default_hint.szhint = TypeHint::SizeHint::S32;
    1344          196 :             break;
    1345           73 :           case UintType::U64:
    1346           73 :             default_hint.szhint = TypeHint::SizeHint::S64;
    1347           73 :             break;
    1348           21 :           case UintType::U128:
    1349           21 :             default_hint.szhint = TypeHint::SizeHint::S128;
    1350           21 :             break;
    1351              :           }
    1352              :       }
    1353              :       break;
    1354              : 
    1355          121 :     case TypeKind::FLOAT:
    1356          121 :       {
    1357          121 :         infer_kind = FLOAT;
    1358          121 :         default_hint.shint = TypeHint::SignedHint::SIGNED;
    1359          121 :         default_hint.kind = hint.get_kind ();
    1360          121 :         switch (hint.as<const FloatType> ()->get_float_kind ())
    1361              :           {
    1362           61 :           case FloatType::F32:
    1363           61 :             default_hint.szhint = TypeHint::SizeHint::S32;
    1364           61 :             break;
    1365              : 
    1366           60 :           case FloatType::F64:
    1367           60 :             default_hint.szhint = TypeHint::SizeHint::S64;
    1368           60 :             break;
    1369              :           }
    1370              :       }
    1371              :       break;
    1372              : 
    1373              :     default:
    1374              :       // TODO bool, char, never??
    1375              :       break;
    1376              :     }
    1377         5476 : }
    1378              : 
    1379              : // ErrorType
    1380              : 
    1381       211698 : ErrorType::ErrorType (HirId ref, std::set<HirId> refs)
    1382              :   : BaseType (ref, ref, KIND,
    1383       211698 :               {Resolver::CanonicalPath::create_empty (), UNDEF_LOCATION}, refs)
    1384       211698 : {}
    1385              : 
    1386           19 : ErrorType::ErrorType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    1387              :   : BaseType (ref, ty_ref, KIND,
    1388           19 :               {Resolver::CanonicalPath::create_empty (), UNDEF_LOCATION}, refs)
    1389           19 : {}
    1390              : 
    1391              : std::string
    1392           57 : ErrorType::get_name () const
    1393              : {
    1394           57 :   return as_string ();
    1395              : }
    1396              : 
    1397              : void
    1398            0 : ErrorType::accept_vis (TyVisitor &vis)
    1399              : {
    1400            0 :   vis.visit (*this);
    1401            0 : }
    1402              : 
    1403              : void
    1404            0 : ErrorType::accept_vis (TyConstVisitor &vis) const
    1405              : {
    1406            0 :   vis.visit (*this);
    1407            0 : }
    1408              : 
    1409              : std::string
    1410           63 : ErrorType::as_string () const
    1411              : {
    1412           63 :   return "<tyty::error>";
    1413              : }
    1414              : 
    1415              : BaseType *
    1416           19 : ErrorType::clone () const
    1417              : {
    1418           19 :   return new ErrorType (get_ref (), get_ty_ref (), get_combined_refs ());
    1419              : }
    1420              : 
    1421              : // Struct Field type
    1422              : 
    1423       248102 : StructFieldType::StructFieldType (HirId ref, std::string name, BaseType *ty,
    1424       248102 :                                   location_t locus)
    1425       248102 :   : ref (ref), name (name), ty (ty), locus (locus)
    1426       248102 : {}
    1427              : 
    1428              : HirId
    1429       247236 : StructFieldType::get_ref () const
    1430              : {
    1431       247236 :   return ref;
    1432              : }
    1433              : 
    1434              : std::string
    1435       473676 : StructFieldType::get_name () const
    1436              : {
    1437       473676 :   return name;
    1438              : }
    1439              : 
    1440              : BaseType *
    1441      1992185 : StructFieldType::get_field_type () const
    1442              : {
    1443      1992185 :   return ty;
    1444              : }
    1445              : 
    1446              : void
    1447         3377 : StructFieldType::set_field_type (BaseType *fty)
    1448              : {
    1449         3377 :   ty = fty;
    1450         3377 : }
    1451              : 
    1452              : void
    1453            0 : StructFieldType::debug () const
    1454              : {
    1455            0 :   rust_debug ("%s", as_string ().c_str ());
    1456            0 : }
    1457              : 
    1458              : location_t
    1459         2277 : StructFieldType::get_locus () const
    1460              : {
    1461         2277 :   return locus;
    1462              : }
    1463              : 
    1464              : std::string
    1465        62264 : StructFieldType::as_string () const
    1466              : {
    1467        62264 :   return name + ":" + get_field_type ()->debug_str ();
    1468              : }
    1469              : 
    1470              : bool
    1471        49801 : StructFieldType::is_equal (const StructFieldType &other) const
    1472              : {
    1473        49801 :   bool names_eq = get_name () == other.get_name ();
    1474              : 
    1475        49801 :   TyTy::BaseType *o = other.get_field_type ();
    1476        49801 :   if (auto op = o->try_as<ParamType> ())
    1477         3785 :     o = op->resolve ();
    1478              : 
    1479        49801 :   bool types_eq = get_field_type ()->is_equal (*o);
    1480              : 
    1481        49801 :   return names_eq && types_eq;
    1482              : }
    1483              : 
    1484              : StructFieldType *
    1485       241621 : StructFieldType::clone () const
    1486              : {
    1487       241621 :   return new StructFieldType (get_ref (), get_name (),
    1488       483242 :                               get_field_type ()->clone (), locus);
    1489              : }
    1490              : 
    1491              : StructFieldType *
    1492         2193 : StructFieldType::monomorphized_clone () const
    1493              : {
    1494         2193 :   return new StructFieldType (get_ref (), get_name (),
    1495         4386 :                               get_field_type ()->monomorphized_clone (), locus);
    1496              : }
    1497              : 
    1498              : // VariantDef
    1499              : 
    1500              : std::string
    1501            6 : VariantDef::variant_type_string (VariantType type)
    1502              : {
    1503            6 :   switch (type)
    1504              :     {
    1505            0 :     case NUM:
    1506            0 :       return "enumeral";
    1507            4 :     case TUPLE:
    1508            4 :       return "tuple";
    1509            2 :     case STRUCT:
    1510            2 :       return "struct";
    1511              :     }
    1512            0 :   rust_unreachable ();
    1513              :   return "";
    1514              : }
    1515              : 
    1516         3574 : VariantDef::VariantDef (HirId id, DefId defid, std::string identifier,
    1517              :                         RustIdent ident,
    1518         3574 :                         tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant)
    1519         7148 :   : id (id), defid (defid), identifier (identifier), ident (ident),
    1520         7148 :     discriminant (std::move (discriminant))
    1521              : 
    1522              : {
    1523         3574 :   type = VariantType::NUM;
    1524         3574 :   fields = {};
    1525         3574 : }
    1526              : 
    1527       215686 : VariantDef::VariantDef (HirId id, DefId defid, std::string identifier,
    1528              :                         RustIdent ident, VariantType type,
    1529              :                         tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant,
    1530       215686 :                         std::vector<StructFieldType *> fields)
    1531       431372 :   : id (id), defid (defid), identifier (identifier), ident (ident), type (type),
    1532       431372 :     discriminant (std::move (discriminant)), fields (fields)
    1533              : {
    1534       215686 :   rust_assert ((type == VariantType::NUM && fields.empty ())
    1535              :                || (type == VariantType::TUPLE || type == VariantType::STRUCT));
    1536       215686 : }
    1537              : 
    1538              : VariantDef &
    1539        12352 : VariantDef::get_error_node ()
    1540              : {
    1541        12352 :   static VariantDef node
    1542         5742 :     = VariantDef (UNKNOWN_HIRID, UNKNOWN_DEFID, "",
    1543         2871 :                   {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
    1544        20965 :                   tl::nullopt);
    1545              : 
    1546        12352 :   return node;
    1547              : }
    1548              : 
    1549              : bool
    1550         1811 : VariantDef::is_error () const
    1551              : {
    1552         1811 :   return get_id () == UNKNOWN_HIRID;
    1553              : }
    1554              : 
    1555              : HirId
    1556        17538 : VariantDef::get_id () const
    1557              : {
    1558        17538 :   return id;
    1559              : }
    1560              : 
    1561              : DefId
    1562            0 : VariantDef::get_defid () const
    1563              : {
    1564            0 :   return defid;
    1565              : }
    1566              : 
    1567              : VariantDef::VariantType
    1568       703080 : VariantDef::get_variant_type () const
    1569              : {
    1570       703080 :   return type;
    1571              : }
    1572              : 
    1573              : bool
    1574            0 : VariantDef::is_data_variant () const
    1575              : {
    1576            0 :   return type != VariantType::NUM;
    1577              : }
    1578              : 
    1579              : bool
    1580        12740 : VariantDef::is_dataless_variant () const
    1581              : {
    1582        12740 :   return type == VariantType::NUM;
    1583              : }
    1584              : 
    1585              : std::string
    1586        16122 : VariantDef::get_identifier () const
    1587              : {
    1588        16122 :   return identifier;
    1589              : }
    1590              : 
    1591              : size_t
    1592      1093990 : VariantDef::num_fields () const
    1593              : {
    1594      1093990 :   return fields.size ();
    1595              : }
    1596              : 
    1597              : StructFieldType *
    1598       250429 : VariantDef::get_field_at_index (size_t index)
    1599              : {
    1600       250429 :   rust_assert (index < fields.size ());
    1601       250429 :   return fields.at (index);
    1602              : }
    1603              : 
    1604              : std::vector<StructFieldType *> &
    1605       563030 : VariantDef::get_fields ()
    1606              : {
    1607       563030 :   return fields;
    1608              : }
    1609              : 
    1610              : bool
    1611        17397 : VariantDef::lookup_field (const std::string &lookup,
    1612              :                           StructFieldType **field_lookup, size_t *index) const
    1613              : {
    1614        17397 :   size_t i = 0;
    1615        88150 :   for (auto &field : fields)
    1616              :     {
    1617        88142 :       if (field->get_name ().compare (lookup) == 0)
    1618              :         {
    1619        17389 :           if (index != nullptr)
    1620        12209 :             *index = i;
    1621              : 
    1622        17389 :           if (field_lookup != nullptr)
    1623        10891 :             *field_lookup = field;
    1624              : 
    1625        17389 :           return true;
    1626              :         }
    1627        70753 :       i++;
    1628              :     }
    1629              :   return false;
    1630              : }
    1631              : 
    1632              : HIR::Expr &
    1633         3568 : VariantDef::get_discriminant ()
    1634              : {
    1635         3568 :   return *discriminant.value ();
    1636              : }
    1637              : 
    1638              : const HIR::Expr &
    1639       107284 : VariantDef::get_discriminant () const
    1640              : {
    1641       107284 :   return *discriminant.value ();
    1642              : }
    1643              : 
    1644              : bool
    1645       230000 : VariantDef::has_discriminant () const
    1646              : {
    1647       230000 :   return discriminant.has_value ();
    1648              : }
    1649              : 
    1650              : std::string
    1651        59718 : VariantDef::as_string () const
    1652              : {
    1653        59718 :   if (type == VariantType::NUM)
    1654        34738 :     return identifier
    1655        34738 :            + (has_discriminant () ? " = " + get_discriminant ().to_string ()
    1656        17369 :                                   : "");
    1657              : 
    1658        42349 :   std::string buffer;
    1659       104613 :   for (size_t i = 0; i < fields.size (); ++i)
    1660              :     {
    1661       124528 :       buffer += fields.at (i)->as_string ();
    1662        62264 :       if ((i + 1) < fields.size ())
    1663        23577 :         buffer += ", ";
    1664              :     }
    1665              : 
    1666        42349 :   if (type == VariantType::TUPLE)
    1667        42686 :     return identifier + " (" + buffer + ")";
    1668              :   else
    1669        42012 :     return identifier + " {" + buffer + "}";
    1670        42349 : }
    1671              : 
    1672              : bool
    1673        55286 : VariantDef::is_equal (const VariantDef &other) const
    1674              : {
    1675        55286 :   if (type != other.type)
    1676              :     return false;
    1677              : 
    1678        55286 :   if (identifier.compare (other.identifier) != 0)
    1679              :     return false;
    1680              : 
    1681        54443 :   if (fields.size () != other.fields.size ())
    1682              :     return false;
    1683              : 
    1684       100968 :   for (size_t i = 0; i < fields.size (); i++)
    1685              :     {
    1686        49801 :       if (!fields.at (i)->is_equal (*other.fields.at (i)))
    1687              :         return false;
    1688              :     }
    1689              : 
    1690              :   return true;
    1691              : }
    1692              : 
    1693              : VariantDef *
    1694       208472 : VariantDef::clone () const
    1695              : {
    1696       208472 :   std::vector<StructFieldType *> cloned_fields;
    1697       450093 :   for (auto &f : fields)
    1698       241621 :     cloned_fields.push_back ((StructFieldType *) f->clone ());
    1699              : 
    1700       208472 :   auto &&discriminant_opt = has_discriminant ()
    1701       208472 :                               ? tl::optional<std::unique_ptr<HIR::Expr>> (
    1702        86476 :                                 get_discriminant ().clone_expr ())
    1703       208472 :                               : tl::nullopt;
    1704              : 
    1705       208472 :   return new VariantDef (id, defid, identifier, ident, type,
    1706       625416 :                          std::move (discriminant_opt), cloned_fields);
    1707       208472 : }
    1708              : 
    1709              : VariantDef *
    1710         4159 : VariantDef::monomorphized_clone () const
    1711              : {
    1712         4159 :   std::vector<StructFieldType *> cloned_fields;
    1713         6352 :   for (auto &f : fields)
    1714         2193 :     cloned_fields.push_back ((StructFieldType *) f->monomorphized_clone ());
    1715              : 
    1716         4159 :   auto discriminant_opt = has_discriminant ()
    1717         4159 :                             ? tl::optional<std::unique_ptr<HIR::Expr>> (
    1718         3439 :                               get_discriminant ().clone_expr ())
    1719         4159 :                             : tl::nullopt;
    1720              : 
    1721         4159 :   return new VariantDef (id, defid, identifier, ident, type,
    1722        12477 :                          std::move (discriminant_opt), cloned_fields);
    1723         4159 : }
    1724              : 
    1725              : const RustIdent &
    1726        32148 : VariantDef::get_ident () const
    1727              : {
    1728        32148 :   return ident;
    1729              : }
    1730              : 
    1731              : // ADTType
    1732              : 
    1733            0 : ADTType::ADTType (DefId id, HirId ref, std::string identifier, RustIdent ident,
    1734              :                   ADTKind adt_kind, std::vector<VariantDef *> variants,
    1735              :                   std::vector<SubstitutionParamMapping> subst_refs,
    1736              :                   SubstitutionArgumentMappings generic_arguments,
    1737            0 :                   RegionConstraints region_constraints, std::set<HirId> refs)
    1738              :   : BaseType (ref, ref, TypeKind::ADT, ident, refs),
    1739              :     SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
    1740              :                      region_constraints),
    1741            0 :     id (id), identifier (identifier), variants (variants), adt_kind (adt_kind)
    1742            0 : {}
    1743              : 
    1744          100 : ADTType::ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
    1745              :                   RustIdent ident, ADTKind adt_kind,
    1746              :                   std::vector<VariantDef *> variants,
    1747              :                   std::vector<SubstitutionParamMapping> subst_refs,
    1748              :                   SubstitutionArgumentMappings generic_arguments,
    1749          100 :                   RegionConstraints region_constraints, std::set<HirId> refs)
    1750              :   : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
    1751              :     SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
    1752              :                      region_constraints),
    1753          300 :     id (id), identifier (identifier), variants (variants), adt_kind (adt_kind)
    1754          100 : {}
    1755              : 
    1756       161176 : ADTType::ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
    1757              :                   RustIdent ident, ADTKind adt_kind,
    1758              :                   std::vector<VariantDef *> variants,
    1759              :                   std::vector<SubstitutionParamMapping> subst_refs,
    1760              :                   ReprOptions repr,
    1761              :                   SubstitutionArgumentMappings generic_arguments,
    1762       161176 :                   RegionConstraints region_constraints, std::set<HirId> refs)
    1763              :   : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
    1764              :     SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
    1765              :                      region_constraints),
    1766       161176 :     id (id), identifier (identifier), variants (variants), adt_kind (adt_kind),
    1767       322352 :     repr (repr)
    1768       161176 : {}
    1769              : 
    1770              : void
    1771        10395 : ADTType::accept_vis (TyVisitor &vis)
    1772              : {
    1773        10395 :   vis.visit (*this);
    1774        10395 : }
    1775              : 
    1776              : void
    1777        31649 : ADTType::accept_vis (TyConstVisitor &vis) const
    1778              : {
    1779        31649 :   vis.visit (*this);
    1780        31649 : }
    1781              : 
    1782              : std::string
    1783        42406 : ADTType::as_string () const
    1784              : {
    1785        42406 :   std::string variants_buffer;
    1786       102124 :   for (size_t i = 0; i < number_of_variants (); ++i)
    1787              :     {
    1788        59718 :       TyTy::VariantDef *variant = variants.at (i);
    1789       119436 :       variants_buffer += variant->as_string ();
    1790        59718 :       if ((i + 1) < number_of_variants ())
    1791        17333 :         variants_buffer += ", ";
    1792              :     }
    1793              : 
    1794       127218 :   return identifier + subst_as_string () + "{" + variants_buffer + "}";
    1795        42406 : }
    1796              : 
    1797              : bool
    1798        50094 : ADTType::is_equal (const BaseType &other) const
    1799              : {
    1800        50094 :   if (get_kind () != other.get_kind ())
    1801              :     return false;
    1802              : 
    1803        37858 :   auto other2 = other.as<const ADTType> ();
    1804        37858 :   if (get_adt_kind () != other2->get_adt_kind ())
    1805              :     return false;
    1806              : 
    1807        36791 :   if (number_of_variants () != other2->number_of_variants ())
    1808              :     return false;
    1809              : 
    1810        36791 :   if (has_substitutions_defined () != other2->has_substitutions_defined ())
    1811              :     return false;
    1812              : 
    1813        36365 :   if (has_substitutions_defined ())
    1814              :     {
    1815        11164 :       if (get_num_substitutions () != other2->get_num_substitutions ())
    1816              :         return false;
    1817              : 
    1818        22246 :       for (size_t i = 0; i < get_num_substitutions (); i++)
    1819              :         {
    1820        11707 :           const SubstitutionParamMapping &a = substitutions.at (i);
    1821        11707 :           const SubstitutionParamMapping &b = other2->substitutions.at (i);
    1822              : 
    1823        11707 :           const auto &aa = a.get_param_ty ();
    1824        11707 :           const auto &bb = b.get_param_ty ();
    1825        11707 :           if (!aa->is_equal (*bb))
    1826              :             return false;
    1827              :         }
    1828              :     }
    1829              : 
    1830        86907 :   for (size_t i = 0; i < number_of_variants (); i++)
    1831              :     {
    1832        55286 :       const TyTy::VariantDef *a = get_variants ().at (i);
    1833        55286 :       const TyTy::VariantDef *b = other2->get_variants ().at (i);
    1834              : 
    1835        55286 :       if (!a->is_equal (*b))
    1836              :         return false;
    1837              :     }
    1838              : 
    1839              :   return true;
    1840              : }
    1841              : 
    1842              : DefId
    1843       158208 : ADTType::get_id () const
    1844              : {
    1845       158208 :   return id;
    1846              : }
    1847              : 
    1848              : BaseType *
    1849       156106 : ADTType::clone () const
    1850              : {
    1851       156106 :   std::vector<VariantDef *> cloned_variants;
    1852       362767 :   for (auto &variant : variants)
    1853       206661 :     cloned_variants.push_back (variant->clone ());
    1854              : 
    1855       156106 :   return new ADTType (get_id (), get_ref (), get_ty_ref (), identifier, ident,
    1856       156106 :                       get_adt_kind (), cloned_variants, clone_substs (),
    1857       156106 :                       get_repr_options (), used_arguments,
    1858       468318 :                       get_region_constraints (), get_combined_refs ());
    1859       156106 : }
    1860              : 
    1861              : static bool
    1862        10773 : handle_substitions (SubstitutionArgumentMappings &subst_mappings,
    1863              :                     StructFieldType *field)
    1864              : {
    1865        10773 :   auto fty = field->get_field_type ();
    1866        10773 :   if (auto p = fty->try_as<ParamType> ())
    1867              :     {
    1868         7537 :       SubstitutionArg arg = SubstitutionArg::error ();
    1869         7537 :       bool ok = subst_mappings.get_argument_for_symbol (p, &arg);
    1870         7537 :       if (ok)
    1871              :         {
    1872         7500 :           auto argt = arg.get_tyty ();
    1873         7500 :           bool arg_is_param = argt->get_kind () == TyTy::TypeKind::PARAM;
    1874         7500 :           bool arg_is_concrete = argt->get_kind () != TyTy::TypeKind::INFER;
    1875              : 
    1876         7500 :           if (arg_is_param || arg_is_concrete)
    1877              :             {
    1878         2306 :               auto new_field = argt->clone ();
    1879         2306 :               new_field->set_ref (fty->get_ref ());
    1880         2306 :               field->set_field_type (new_field);
    1881              :             }
    1882              :           else
    1883              :             {
    1884         5194 :               field->get_field_type ()->set_ty_ref (argt->get_ref ());
    1885              :             }
    1886              :         }
    1887              :     }
    1888         3236 :   else if (fty->has_substitutions_defined () || !fty->is_concrete ())
    1889              :     {
    1890         1071 :       BaseType *concrete
    1891         1071 :         = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings);
    1892              : 
    1893         1071 :       if (concrete->get_kind () == TyTy::TypeKind::ERROR)
    1894              :         {
    1895            0 :           rust_error_at (subst_mappings.get_locus (),
    1896              :                          "Failed to resolve field substitution type: %s",
    1897            0 :                          fty->as_string ().c_str ());
    1898            0 :           return false;
    1899              :         }
    1900              : 
    1901         1071 :       auto new_field = concrete->clone ();
    1902         1071 :       new_field->set_ref (fty->get_ref ());
    1903         1071 :       field->set_field_type (new_field);
    1904              :     }
    1905              : 
    1906              :   return true;
    1907              : }
    1908              : 
    1909              : ADTType *
    1910         8147 : ADTType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
    1911              : {
    1912         8147 :   auto adt = clone ()->as<ADTType> ();
    1913         8147 :   adt->set_ty_ref (mappings.get_next_hir_id ());
    1914         8147 :   adt->used_arguments = subst_mappings;
    1915              : 
    1916        17059 :   for (auto &sub : adt->get_substs ())
    1917              :     {
    1918         8912 :       SubstitutionArg arg = SubstitutionArg::error ();
    1919         8912 :       bool ok
    1920         8912 :         = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg);
    1921         8912 :       if (ok)
    1922         8857 :         sub.fill_param_ty (subst_mappings, subst_mappings.get_locus ());
    1923              :     }
    1924              : 
    1925        20887 :   for (auto &variant : adt->get_variants ())
    1926              :     {
    1927        12740 :       if (variant->is_dataless_variant ())
    1928         4114 :         continue;
    1929              : 
    1930        19399 :       for (auto &field : variant->get_fields ())
    1931              :         {
    1932        10773 :           bool ok = ::Rust::TyTy::handle_substitions (subst_mappings, field);
    1933        10773 :           if (!ok)
    1934         8147 :             return adt;
    1935              :         }
    1936              :     }
    1937              : 
    1938              :   return adt;
    1939              : }
    1940              : 
    1941              : // TupleType
    1942              : 
    1943         5782 : TupleType::TupleType (HirId ref, location_t locus, std::vector<TyVar> fields,
    1944         5782 :                       std::set<HirId> refs)
    1945         5782 :   : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), locus},
    1946              :               refs),
    1947        11564 :     fields (fields)
    1948         5782 : {}
    1949              : 
    1950        14706 : TupleType::TupleType (HirId ref, HirId ty_ref, location_t locus,
    1951        14706 :                       std::vector<TyVar> fields, std::set<HirId> refs)
    1952              :   : BaseType (ref, ty_ref, KIND,
    1953        14706 :               {Resolver::CanonicalPath::create_empty (), locus}, refs),
    1954        29412 :     fields (fields)
    1955        14706 : {}
    1956              : 
    1957              : TupleType *
    1958        32528 : TupleType::get_unit_type ()
    1959              : {
    1960        32528 :   static TupleType *ret = nullptr;
    1961        32528 :   if (ret == nullptr)
    1962         9012 :     ret = new TupleType (Analysis::Mappings::get ().get_next_hir_id (),
    1963         9012 :                          BUILTINS_LOCATION);
    1964        32528 :   return ret;
    1965              : }
    1966              : 
    1967              : size_t
    1968       133094 : TupleType::num_fields () const
    1969              : {
    1970       133094 :   return fields.size ();
    1971              : }
    1972              : 
    1973              : const std::vector<TyVar> &
    1974       171957 : TupleType::get_fields () const
    1975              : {
    1976       171957 :   return fields;
    1977              : }
    1978              : 
    1979              : void
    1980          412 : TupleType::accept_vis (TyVisitor &vis)
    1981              : {
    1982          412 :   vis.visit (*this);
    1983          412 : }
    1984              : 
    1985              : void
    1986        17032 : TupleType::accept_vis (TyConstVisitor &vis) const
    1987              : {
    1988        17032 :   vis.visit (*this);
    1989        17032 : }
    1990              : 
    1991              : std::string
    1992        22441 : TupleType::as_string () const
    1993              : {
    1994        22441 :   size_t i = 0;
    1995        22441 :   std::string fields_buffer;
    1996        29772 :   for (const TyVar &field : get_fields ())
    1997              :     {
    1998        14662 :       fields_buffer += field.get_tyty ()->as_string ();
    1999         7331 :       bool has_next = (i + 1) < get_fields ().size ();
    2000         7331 :       fields_buffer += has_next ? ", " : "";
    2001         7331 :       i++;
    2002              :     }
    2003        44882 :   return "(" + fields_buffer + ")";
    2004        22441 : }
    2005              : 
    2006              : std::string
    2007       115601 : TupleType::get_name () const
    2008              : {
    2009       115601 :   size_t i = 0;
    2010       115601 :   std::string fields_buffer;
    2011       136758 :   for (const TyVar &field : get_fields ())
    2012              :     {
    2013        42314 :       fields_buffer += field.get_tyty ()->get_name ();
    2014        21157 :       bool has_next = (i + 1) < get_fields ().size ();
    2015        21157 :       fields_buffer += has_next ? ", " : "";
    2016        21157 :       i++;
    2017              :     }
    2018       231202 :   return "(" + fields_buffer + ")";
    2019       115601 : }
    2020              : 
    2021              : BaseType *
    2022        15677 : TupleType::get_field (size_t index) const
    2023              : {
    2024        15677 :   return fields.at (index).get_tyty ();
    2025              : }
    2026              : 
    2027              : bool
    2028        12767 : TupleType::is_equal (const BaseType &other) const
    2029              : {
    2030        12767 :   if (get_kind () != other.get_kind ())
    2031              :     return false;
    2032              : 
    2033        12732 :   auto other2 = other.as<const TupleType> ();
    2034        12732 :   if (num_fields () != other2->num_fields ())
    2035              :     return false;
    2036              : 
    2037        14769 :   for (size_t i = 0; i < num_fields (); i++)
    2038              :     {
    2039         2209 :       if (!get_field (i)->is_equal (*other2->get_field (i)))
    2040              :         return false;
    2041              :     }
    2042              :   return true;
    2043              : }
    2044              : 
    2045              : BaseType *
    2046        10101 : TupleType::clone () const
    2047              : {
    2048        10101 :   std::vector<TyVar> cloned_fields;
    2049        17814 :   for (const auto &f : fields)
    2050         7713 :     cloned_fields.push_back (f.clone ());
    2051              : 
    2052        10101 :   return new TupleType (get_ref (), get_ty_ref (), get_ident ().locus,
    2053        20202 :                         cloned_fields, get_combined_refs ());
    2054        10101 : }
    2055              : 
    2056              : TupleType *
    2057          264 : TupleType::handle_substitions (SubstitutionArgumentMappings &mappings)
    2058              : {
    2059          264 :   auto &mappings_table = Analysis::Mappings::get ();
    2060              : 
    2061          264 :   auto tuple = clone ()->as<TupleType> ();
    2062          264 :   tuple->set_ref (mappings_table.get_next_hir_id ());
    2063          264 :   tuple->set_ty_ref (mappings_table.get_next_hir_id ());
    2064              : 
    2065          767 :   for (size_t i = 0; i < tuple->fields.size (); i++)
    2066              :     {
    2067          503 :       TyVar &field = fields.at (i);
    2068          503 :       if (!field.get_tyty ()->is_concrete ())
    2069              :         {
    2070          311 :           BaseType *concrete
    2071          311 :             = Resolver::SubstMapperInternal::Resolve (field.get_tyty (),
    2072              :                                                       mappings);
    2073          311 :           tuple->fields[i]
    2074          311 :             = TyVar::subst_covariant_var (field.get_tyty (), concrete);
    2075              :         }
    2076              :     }
    2077              : 
    2078          264 :   return tuple;
    2079              : }
    2080              : 
    2081              : void
    2082        20421 : FnType::accept_vis (TyVisitor &vis)
    2083              : {
    2084        20421 :   vis.visit (*this);
    2085        20421 : }
    2086              : 
    2087              : void
    2088        16241 : FnType::accept_vis (TyConstVisitor &vis) const
    2089              : {
    2090        16241 :   vis.visit (*this);
    2091        16241 : }
    2092              : 
    2093              : std::string
    2094        93122 : FnType::as_string () const
    2095              : {
    2096        93122 :   std::string params_str = "";
    2097       216345 :   for (auto &param : params)
    2098              :     {
    2099       123223 :       auto &pattern = param.get_pattern ();
    2100       123223 :       auto ty = param.get_type ();
    2101       369669 :       params_str += pattern.to_string () + " " + ty->as_string ();
    2102       123223 :       params_str += ",";
    2103              :     }
    2104              : 
    2105        93122 :   std::string ret_str = type->as_string ();
    2106       279366 :   return "fn" + subst_as_string () + " (" + params_str + ") -> " + ret_str;
    2107        93122 : }
    2108              : 
    2109              : bool
    2110         8572 : FnType::is_equal (const BaseType &other) const
    2111              : {
    2112         8572 :   if (get_kind () != other.get_kind ())
    2113              :     return false;
    2114              : 
    2115         8572 :   auto &other2 = static_cast<const FnType &> (other);
    2116        25716 :   if (get_identifier ().compare (other2.get_identifier ()) != 0)
    2117              :     return false;
    2118              : 
    2119         8572 :   if (!get_return_type ()->is_equal (*other2.get_return_type ()))
    2120              :     return false;
    2121              : 
    2122         7038 :   if (has_substitutions_defined () != other2.has_substitutions_defined ())
    2123              :     return false;
    2124              : 
    2125         4189 :   if (has_substitutions_defined ())
    2126              :     {
    2127          609 :       if (get_num_substitutions () != other2.get_num_substitutions ())
    2128              :         return false;
    2129              : 
    2130              :       const FnType &ofn = static_cast<const FnType &> (other);
    2131          911 :       for (size_t i = 0; i < get_num_substitutions (); i++)
    2132              :         {
    2133          590 :           const SubstitutionParamMapping &a = get_substs ().at (i);
    2134          590 :           const SubstitutionParamMapping &b = ofn.get_substs ().at (i);
    2135              : 
    2136          590 :           const auto *pa = a.get_param_ty ();
    2137          590 :           const auto *pb = b.get_param_ty ();
    2138          590 :           if (!pa->is_equal (*pb))
    2139              :             return false;
    2140              :         }
    2141              :     }
    2142              : 
    2143         3901 :   if (num_params () != other2.num_params ())
    2144              :     return false;
    2145              : 
    2146        10406 :   for (size_t i = 0; i < num_params (); i++)
    2147              :     {
    2148         6506 :       auto lhs = param_at (i).get_type ();
    2149         6506 :       auto rhs = other2.param_at (i).get_type ();
    2150         6506 :       if (!lhs->is_equal (*rhs))
    2151              :         return false;
    2152              :     }
    2153              :   return true;
    2154              : }
    2155              : 
    2156              : BaseType *
    2157        12889 : FnType::clone () const
    2158              : {
    2159        12889 :   std::vector<TyTy::FnParam> cloned_params;
    2160        32269 :   for (auto &p : params)
    2161        19380 :     cloned_params.push_back (p.clone ());
    2162              : 
    2163        25778 :   return new FnType (get_ref (), get_ty_ref (), get_id (), get_identifier (),
    2164        12889 :                      ident, flags, abi, std::move (cloned_params),
    2165        12889 :                      get_return_type ()->clone (), clone_substs (),
    2166              :                      get_substitution_arguments (), get_region_constraints (),
    2167        64445 :                      get_combined_refs ());
    2168        12889 : }
    2169              : 
    2170              : FnType *
    2171        11478 : FnType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
    2172              : {
    2173        11478 :   FnType *fn = static_cast<FnType *> (clone ());
    2174        11478 :   fn->set_ty_ref (mappings.get_next_hir_id ());
    2175        11478 :   fn->used_arguments = subst_mappings;
    2176              : 
    2177        27287 :   for (auto &sub : fn->get_substs ())
    2178              :     {
    2179        15809 :       SubstitutionArg arg = SubstitutionArg::error ();
    2180              : 
    2181        15809 :       bool ok
    2182        15809 :         = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg);
    2183        15809 :       if (ok)
    2184              :         {
    2185        15340 :           sub.fill_param_ty (subst_mappings, subst_mappings.get_locus ());
    2186              :         }
    2187              :     }
    2188              : 
    2189        11478 :   auto fty = fn->get_return_type ();
    2190        11478 :   bool is_param_ty = fty->get_kind () == TypeKind::PARAM;
    2191        11478 :   if (is_param_ty)
    2192              :     {
    2193         2882 :       ParamType *p = static_cast<ParamType *> (fty);
    2194              : 
    2195         2882 :       SubstitutionArg arg = SubstitutionArg::error ();
    2196         2882 :       bool ok = subst_mappings.get_argument_for_symbol (p, &arg);
    2197         2882 :       if (ok)
    2198              :         {
    2199         2875 :           auto argt = arg.get_tyty ();
    2200         2875 :           bool arg_is_param = argt->get_kind () == TyTy::TypeKind::PARAM;
    2201         2875 :           bool arg_is_concrete = argt->get_kind () != TyTy::TypeKind::INFER;
    2202              : 
    2203         2875 :           if (arg_is_param || arg_is_concrete)
    2204              :             {
    2205         1413 :               auto new_field = argt->clone ();
    2206         1413 :               new_field->set_ref (fty->get_ref ());
    2207         1413 :               fn->type = new_field;
    2208              :             }
    2209              :           else
    2210              :             {
    2211         1462 :               fty->set_ty_ref (argt->get_ref ());
    2212              :             }
    2213              :         }
    2214              :     }
    2215         8596 :   else if (fty->needs_generic_substitutions () || !fty->is_concrete ())
    2216              :     {
    2217         1840 :       BaseType *concrete
    2218         1840 :         = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings);
    2219              : 
    2220         1840 :       if (concrete == nullptr || concrete->get_kind () == TyTy::TypeKind::ERROR)
    2221              :         {
    2222            0 :           rust_error_at (subst_mappings.get_locus (),
    2223              :                          "Failed to resolve field substitution type: %s",
    2224            0 :                          fty->as_string ().c_str ());
    2225            0 :           return nullptr;
    2226              :         }
    2227              : 
    2228         1840 :       auto new_field = concrete->clone ();
    2229         1840 :       new_field->set_ref (fty->get_ref ());
    2230         1840 :       fn->type = new_field;
    2231              :     }
    2232              : 
    2233        28660 :   for (auto &param : fn->get_params ())
    2234              :     {
    2235        17182 :       auto fty = param.get_type ();
    2236              : 
    2237        17182 :       bool is_param_ty = fty->get_kind () == TypeKind::PARAM;
    2238        17182 :       if (is_param_ty)
    2239              :         {
    2240         5125 :           ParamType *p = static_cast<ParamType *> (fty);
    2241              : 
    2242         5125 :           SubstitutionArg arg = SubstitutionArg::error ();
    2243         5125 :           bool ok = subst_mappings.get_argument_for_symbol (p, &arg);
    2244         5125 :           if (ok)
    2245              :             {
    2246         5074 :               auto argt = arg.get_tyty ();
    2247         5074 :               bool arg_is_param = argt->get_kind () == TyTy::TypeKind::PARAM;
    2248         5074 :               bool arg_is_concrete = argt->get_kind () != TyTy::TypeKind::INFER;
    2249              : 
    2250         5074 :               if (arg_is_param || arg_is_concrete)
    2251              :                 {
    2252         2112 :                   auto new_field = argt->clone ();
    2253         2112 :                   new_field->set_ref (fty->get_ref ());
    2254         2112 :                   param.set_type (new_field);
    2255              :                 }
    2256              :               else
    2257              :                 {
    2258         2962 :                   fty->set_ty_ref (argt->get_ref ());
    2259              :                 }
    2260              :             }
    2261              :         }
    2262        12057 :       else if (fty->has_substitutions_defined () || !fty->is_concrete ())
    2263              :         {
    2264        10898 :           BaseType *concrete
    2265        10898 :             = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings);
    2266              : 
    2267        10898 :           if (concrete == nullptr
    2268        10898 :               || concrete->get_kind () == TyTy::TypeKind::ERROR)
    2269              :             {
    2270            0 :               rust_error_at (subst_mappings.get_locus (),
    2271              :                              "Failed to resolve field substitution type: %s",
    2272            0 :                              fty->as_string ().c_str ());
    2273            0 :               return nullptr;
    2274              :             }
    2275              : 
    2276        10898 :           auto new_field = concrete->clone ();
    2277        10898 :           new_field->set_ref (fty->get_ref ());
    2278        10898 :           param.set_type (new_field);
    2279              :         }
    2280              :     }
    2281              : 
    2282              :   return fn;
    2283              : }
    2284              : 
    2285              : void
    2286           46 : FnPtr::accept_vis (TyVisitor &vis)
    2287              : {
    2288           46 :   vis.visit (*this);
    2289           46 : }
    2290              : 
    2291              : void
    2292          186 : FnPtr::accept_vis (TyConstVisitor &vis) const
    2293              : {
    2294          186 :   vis.visit (*this);
    2295          186 : }
    2296              : 
    2297              : std::string
    2298         9412 : FnPtr::as_string () const
    2299              : {
    2300         9412 :   std::string params_str;
    2301              : 
    2302         9412 :   auto &params = get_params ();
    2303        10128 :   for (auto &p : params)
    2304              :     {
    2305         2148 :       params_str += p.get_tyty ()->as_string () + " ,";
    2306              :     }
    2307              : 
    2308         9412 :   std::string unsafety = "";
    2309         9412 :   if (get_unsafety () == Unsafety::Unsafe)
    2310         3832 :     unsafety = "unsafe ";
    2311              : 
    2312         9412 :   std::string abi = get_string_from_abi (get_abi ());
    2313        37648 :   return unsafety + "abi:" + abi + " " + "fnptr (" + params_str + ") -> "
    2314        28236 :          + get_return_type ()->as_string ();
    2315         9412 : }
    2316              : 
    2317              : bool
    2318          322 : FnPtr::is_equal (const BaseType &other) const
    2319              : {
    2320          322 :   if (get_kind () != other.get_kind ())
    2321              :     return false;
    2322              : 
    2323          110 :   auto other2 = static_cast<const FnPtr &> (other);
    2324          110 :   auto this_ret_type = get_return_type ();
    2325          110 :   auto other_ret_type = other2.get_return_type ();
    2326          110 :   if (this_ret_type->is_equal (*other_ret_type))
    2327              :     return false;
    2328              : 
    2329           27 :   if (num_params () != other2.num_params ())
    2330              :     return false;
    2331              : 
    2332           27 :   for (size_t i = 0; i < num_params (); i++)
    2333              :     {
    2334            0 :       if (!get_param_type_at (i)->is_equal (*other2.get_param_type_at (i)))
    2335              :         return false;
    2336              :     }
    2337              :   return true;
    2338          110 : }
    2339              : 
    2340              : BaseType *
    2341         1384 : FnPtr::clone () const
    2342              : {
    2343         1384 :   std::vector<TyVar> cloned_params;
    2344         1384 :   cloned_params.reserve (params.size ());
    2345              : 
    2346         1415 :   for (auto &p : params)
    2347           31 :     cloned_params.emplace_back (p.get_ref ());
    2348              : 
    2349         1384 :   return new FnPtr (get_ref (), get_ty_ref (), ident.locus,
    2350              :                     std::move (cloned_params), result_type, get_abi (),
    2351         1384 :                     get_unsafety (), get_combined_refs ());
    2352         1384 : }
    2353              : 
    2354              : FnPtr *
    2355            8 : FnPtr::handle_substitions (SubstitutionArgumentMappings &mappings)
    2356              : {
    2357            8 :   auto &mappings_table = Analysis::Mappings::get ();
    2358              : 
    2359            8 :   auto fn = clone ()->as<FnPtr> ();
    2360            8 :   fn->set_ref (mappings_table.get_next_hir_id ());
    2361            8 :   fn->set_ty_ref (mappings_table.get_next_hir_id ());
    2362              : 
    2363            8 :   if (!fn->result_type.get_tyty ()->is_concrete ())
    2364              :     {
    2365            4 :       BaseType *concrete
    2366            4 :         = Resolver::SubstMapperInternal::Resolve (fn->result_type.get_tyty (),
    2367              :                                                   mappings);
    2368            4 :       fn->result_type
    2369            4 :         = TyVar::subst_covariant_var (fn->result_type.get_tyty (), concrete);
    2370              :     }
    2371              : 
    2372           16 :   for (size_t i = 0; i < fn->params.size (); i++)
    2373              :     {
    2374            8 :       TyVar &field = fn->params.at (i);
    2375            8 :       if (!field.get_tyty ()->is_concrete ())
    2376              :         {
    2377            4 :           BaseType *concrete
    2378            4 :             = Resolver::SubstMapperInternal::Resolve (field.get_tyty (),
    2379              :                                                       mappings);
    2380            4 :           fn->params[i]
    2381            4 :             = TyVar::subst_covariant_var (field.get_tyty (), concrete);
    2382              :         }
    2383              :     }
    2384              : 
    2385            8 :   return fn;
    2386              : }
    2387              : 
    2388              : void
    2389            0 : ClosureType::accept_vis (TyVisitor &vis)
    2390              : {
    2391            0 :   vis.visit (*this);
    2392            0 : }
    2393              : 
    2394              : void
    2395          243 : ClosureType::accept_vis (TyConstVisitor &vis) const
    2396              : {
    2397          243 :   vis.visit (*this);
    2398          243 : }
    2399              : 
    2400              : std::string
    2401         2275 : ClosureType::as_string () const
    2402              : {
    2403         2275 :   std::string params_buf = parameters->as_string ();
    2404         6825 :   return "|" + params_buf + "| {" + result_type.get_tyty ()->as_string () + "}";
    2405         2275 : }
    2406              : 
    2407              : bool
    2408          161 : ClosureType::is_equal (const BaseType &other) const
    2409              : {
    2410          161 :   if (other.get_kind () != TypeKind::CLOSURE)
    2411              :     return false;
    2412              : 
    2413          161 :   const ClosureType &other2 = static_cast<const ClosureType &> (other);
    2414          161 :   if (get_def_id () != other2.get_def_id ())
    2415              :     return false;
    2416              : 
    2417          161 :   if (!get_parameters ().is_equal (other2.get_parameters ()))
    2418              :     return false;
    2419              : 
    2420          161 :   return get_result_type ().is_equal (other2.get_result_type ());
    2421              : }
    2422              : 
    2423              : BaseType *
    2424          319 : ClosureType::clone () const
    2425              : {
    2426          319 :   return new ClosureType (get_ref (), get_ty_ref (), ident, id,
    2427          319 :                           (TyTy::TupleType *) parameters->clone (), result_type,
    2428          638 :                           clone_substs (), captures, get_combined_refs (),
    2429         1276 :                           specified_bounds);
    2430              : }
    2431              : 
    2432              : ClosureType *
    2433            0 : ClosureType::handle_substitions (SubstitutionArgumentMappings &mappings)
    2434              : {
    2435            0 :   rust_unreachable ();
    2436              :   return nullptr;
    2437              : }
    2438              : 
    2439              : void
    2440          100 : ClosureType::setup_fn_once_output () const
    2441              : {
    2442              :   // lookup the lang items
    2443          100 :   auto fn_once_lookup = mappings.lookup_lang_item (LangItem::Kind::FN_ONCE);
    2444          100 :   auto fn_once_output_lookup
    2445          100 :     = mappings.lookup_lang_item (LangItem::Kind::FN_ONCE_OUTPUT);
    2446          100 :   if (!fn_once_lookup)
    2447              :     {
    2448            0 :       rust_fatal_error (UNKNOWN_LOCATION,
    2449              :                         "Missing required %<fn_once%> lang item");
    2450              :       return;
    2451              :     }
    2452          100 :   if (!fn_once_output_lookup)
    2453              :     {
    2454            0 :       rust_fatal_error (UNKNOWN_LOCATION,
    2455              :                         "Missing required %<fn_once_ouput%> lang item");
    2456              :       return;
    2457              :     }
    2458              : 
    2459          100 :   DefId &trait_id = fn_once_lookup.value ();
    2460          100 :   DefId &trait_item_id = fn_once_output_lookup.value ();
    2461              : 
    2462              :   // resolve to the trait
    2463          100 :   HIR::Item *item = mappings.lookup_defid (trait_id).value ();
    2464          100 :   rust_assert (item->get_item_kind () == HIR::Item::ItemKind::Trait);
    2465          100 :   HIR::Trait *trait = static_cast<HIR::Trait *> (item);
    2466              : 
    2467          100 :   Resolver::TraitReference *trait_ref
    2468          100 :     = Resolver::TraitResolver::Resolve (*trait);
    2469          100 :   rust_assert (!trait_ref->is_error ());
    2470              : 
    2471              :   // resolve to trait item
    2472          100 :   HIR::TraitItem *trait_item
    2473          100 :     = mappings.lookup_trait_item_defid (trait_item_id).value ();
    2474          100 :   rust_assert (trait_item->get_item_kind ()
    2475              :                == HIR::TraitItem::TraitItemKind::TYPE);
    2476          100 :   std::string item_identifier = trait_item->trait_identifier ();
    2477              : 
    2478              :   // setup associated types  #[lang = "fn_once_output"]
    2479          100 :   Resolver::TraitItemReference *item_reference = nullptr;
    2480          100 :   bool found = trait_ref->lookup_trait_item_by_type (
    2481              :     item_identifier, Resolver::TraitItemReference::TraitItemType::TYPE,
    2482              :     &item_reference);
    2483          100 :   rust_assert (found);
    2484              : 
    2485              :   // setup
    2486          100 :   item_reference->associated_type_set (&get_result_type ());
    2487          100 : }
    2488              : 
    2489              : void
    2490          107 : ArrayType::accept_vis (TyVisitor &vis)
    2491              : {
    2492          107 :   vis.visit (*this);
    2493          107 : }
    2494              : 
    2495              : void
    2496         4092 : ArrayType::accept_vis (TyConstVisitor &vis) const
    2497              : {
    2498         4092 :   vis.visit (*this);
    2499         4092 : }
    2500              : 
    2501              : std::string
    2502        56839 : ArrayType::as_string () const
    2503              : {
    2504        56839 :   auto cap = get_capacity ();
    2505        56839 :   std::string capacity_str = cap->as_string ();
    2506              : 
    2507       170517 :   return "[" + get_element_type ()->as_string () + "; " + capacity_str + "]";
    2508        56839 : }
    2509              : 
    2510              : bool
    2511         2405 : ArrayType::is_equal (const BaseType &other) const
    2512              : {
    2513         2405 :   if (get_kind () != other.get_kind ())
    2514              :     return false;
    2515              : 
    2516         2352 :   auto other2 = static_cast<const ArrayType &> (other);
    2517              : 
    2518         2352 :   auto this_element_type = get_element_type ();
    2519         2352 :   auto other_element_type = other2.get_element_type ();
    2520              : 
    2521         2352 :   return this_element_type->is_equal (*other_element_type);
    2522         2352 : }
    2523              : 
    2524              : BaseType *
    2525        84772 : ArrayType::get_element_type () const
    2526              : {
    2527        84772 :   return element_type.get_tyty ();
    2528              : }
    2529              : 
    2530              : const TyVar &
    2531           80 : ArrayType::get_var_element_type () const
    2532              : {
    2533           80 :   return element_type;
    2534              : }
    2535              : 
    2536              : BaseType *
    2537        79303 : ArrayType::get_capacity () const
    2538              : {
    2539        79303 :   return capacity.get_tyty ();
    2540              : }
    2541              : 
    2542              : BaseType *
    2543          784 : ArrayType::clone () const
    2544              : {
    2545         1568 :   return new ArrayType (get_ref (), get_ty_ref (), ident.locus, capacity,
    2546          784 :                         element_type, get_combined_refs ());
    2547              : }
    2548              : 
    2549              : ArrayType *
    2550           57 : ArrayType::handle_substitions (SubstitutionArgumentMappings &mappings)
    2551              : {
    2552           57 :   auto &mappings_table = Analysis::Mappings::get ();
    2553              : 
    2554           57 :   ArrayType *ref = static_cast<ArrayType *> (clone ());
    2555           57 :   ref->set_ty_ref (mappings_table.get_next_hir_id ());
    2556              : 
    2557              :   // might be &T or &ADT so this needs to be recursive
    2558           57 :   auto base = ref->get_element_type ();
    2559           57 :   BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings);
    2560           57 :   ref->element_type = TyVar::subst_covariant_var (base, concrete);
    2561              : 
    2562              :   // handle capacity type
    2563           57 :   auto cap = ref->get_capacity ();
    2564           57 :   BaseType *concrete_cap
    2565           57 :     = Resolver::SubstMapperInternal::Resolve (cap, mappings);
    2566           57 :   rust_assert (concrete_cap->get_kind () == TyTy::TypeKind::CONST);
    2567           57 :   ref->capacity = TyVar::subst_covariant_var (cap, concrete_cap);
    2568              : 
    2569           57 :   return ref;
    2570              : }
    2571              : 
    2572              : void
    2573         1418 : SliceType::accept_vis (TyVisitor &vis)
    2574              : {
    2575         1418 :   vis.visit (*this);
    2576         1418 : }
    2577              : 
    2578              : void
    2579          602 : SliceType::accept_vis (TyConstVisitor &vis) const
    2580              : {
    2581          602 :   vis.visit (*this);
    2582          602 : }
    2583              : 
    2584              : std::string
    2585        50684 : SliceType::as_string () const
    2586              : {
    2587       101368 :   return "[" + get_element_type ()->as_string () + "]";
    2588              : }
    2589              : 
    2590              : bool
    2591         4711 : SliceType::is_equal (const BaseType &other) const
    2592              : {
    2593         4711 :   if (get_kind () != other.get_kind ())
    2594              :     return false;
    2595              : 
    2596         3668 :   auto other2 = static_cast<const SliceType &> (other);
    2597              : 
    2598         3668 :   auto this_element_type = get_element_type ();
    2599         3668 :   auto other_element_type = other2.get_element_type ();
    2600              : 
    2601         3668 :   return this_element_type->is_equal (*other_element_type);
    2602         3668 : }
    2603              : 
    2604              : BaseType *
    2605        80812 : SliceType::get_element_type () const
    2606              : {
    2607        80812 :   return element_type.get_tyty ();
    2608              : }
    2609              : 
    2610              : const TyVar &
    2611          161 : SliceType::get_var_element_type () const
    2612              : {
    2613          161 :   return element_type;
    2614              : }
    2615              : 
    2616              : BaseType *
    2617        49901 : SliceType::clone () const
    2618              : {
    2619        99802 :   return new SliceType (get_ref (), get_ty_ref (), ident.locus,
    2620        49901 :                         element_type.clone (), get_combined_refs ());
    2621              : }
    2622              : 
    2623              : SliceType *
    2624         1128 : SliceType::handle_substitions (SubstitutionArgumentMappings &mappings)
    2625              : {
    2626         1128 :   auto &mappings_table = Analysis::Mappings::get ();
    2627              : 
    2628         1128 :   SliceType *ref = static_cast<SliceType *> (clone ());
    2629         1128 :   ref->set_ty_ref (mappings_table.get_next_hir_id ());
    2630              : 
    2631              :   // might be &T or &ADT so this needs to be recursive
    2632         1128 :   auto base = ref->get_element_type ();
    2633         1128 :   BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings);
    2634         1128 :   ref->element_type = TyVar::subst_covariant_var (base, concrete);
    2635              : 
    2636         1128 :   return ref;
    2637              : }
    2638              : 
    2639              : // BoolType
    2640              : 
    2641         4506 : BoolType::BoolType (HirId ref, std::set<HirId> refs)
    2642              :   : BaseType (ref, ref, KIND,
    2643         4506 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2644         9012 :               refs)
    2645         4506 : {}
    2646              : 
    2647        37295 : BoolType::BoolType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    2648              :   : BaseType (ref, ty_ref, KIND,
    2649        37295 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2650        74590 :               refs)
    2651        37295 : {}
    2652              : 
    2653              : std::string
    2654       277422 : BoolType::get_name () const
    2655              : {
    2656       277422 :   return as_string ();
    2657              : }
    2658              : 
    2659              : void
    2660          206 : BoolType::accept_vis (TyVisitor &vis)
    2661              : {
    2662          206 :   vis.visit (*this);
    2663          206 : }
    2664              : 
    2665              : void
    2666        10391 : BoolType::accept_vis (TyConstVisitor &vis) const
    2667              : {
    2668        10391 :   vis.visit (*this);
    2669        10391 : }
    2670              : 
    2671              : std::string
    2672       325120 : BoolType::as_string () const
    2673              : {
    2674       325120 :   return "bool";
    2675              : }
    2676              : 
    2677              : BaseType *
    2678        37295 : BoolType::clone () const
    2679              : {
    2680        37295 :   return new BoolType (get_ref (), get_ty_ref (), get_combined_refs ());
    2681              : }
    2682              : 
    2683              : // IntType
    2684              : 
    2685        22530 : IntType::IntType (HirId ref, IntKind kind, std::set<HirId> refs)
    2686              :   : BaseType (ref, ref, KIND,
    2687        22530 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2688              :               refs),
    2689        45060 :     int_kind (kind)
    2690        22530 : {}
    2691              : 
    2692       300649 : IntType::IntType (HirId ref, HirId ty_ref, IntKind kind, std::set<HirId> refs)
    2693              :   : BaseType (ref, ty_ref, KIND,
    2694       300649 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2695              :               refs),
    2696       601298 :     int_kind (kind)
    2697       300649 : {}
    2698              : 
    2699              : std::string
    2700      2321936 : IntType::get_name () const
    2701              : {
    2702      2321936 :   return as_string ();
    2703              : }
    2704              : 
    2705              : IntType::IntKind
    2706       775770 : IntType::get_int_kind () const
    2707              : {
    2708       775770 :   return int_kind;
    2709              : }
    2710              : 
    2711              : void
    2712         2007 : IntType::accept_vis (TyVisitor &vis)
    2713              : {
    2714         2007 :   vis.visit (*this);
    2715         2007 : }
    2716              : 
    2717              : void
    2718        80333 : IntType::accept_vis (TyConstVisitor &vis) const
    2719              : {
    2720        80333 :   vis.visit (*this);
    2721        80333 : }
    2722              : 
    2723              : std::string
    2724      2513097 : IntType::as_string () const
    2725              : {
    2726      2513097 :   switch (int_kind)
    2727              :     {
    2728       395882 :     case I8:
    2729       395882 :       return "i8";
    2730       330078 :     case I16:
    2731       330078 :       return "i16";
    2732      1416699 :     case I32:
    2733      1416699 :       return "i32";
    2734       329048 :     case I64:
    2735       329048 :       return "i64";
    2736        41390 :     case I128:
    2737        41390 :       return "i128";
    2738              :     }
    2739            0 :   rust_unreachable ();
    2740              :   return "__unknown_int_type";
    2741              : }
    2742              : 
    2743              : BaseType *
    2744       300649 : IntType::clone () const
    2745              : {
    2746       300649 :   return new IntType (get_ref (), get_ty_ref (), get_int_kind (),
    2747       300649 :                       get_combined_refs ());
    2748              : }
    2749              : 
    2750              : bool
    2751        87959 : IntType::is_equal (const BaseType &other) const
    2752              : {
    2753        87959 :   if (!BaseType::is_equal (other))
    2754              :     return false;
    2755              : 
    2756        67562 :   const IntType &o = static_cast<const IntType &> (other);
    2757        67562 :   return get_int_kind () == o.get_int_kind ();
    2758              : }
    2759              : 
    2760              : // UintType
    2761              : 
    2762        22530 : UintType::UintType (HirId ref, UintKind kind, std::set<HirId> refs)
    2763              :   : BaseType (ref, ref, KIND,
    2764        22530 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2765              :               refs),
    2766        45060 :     uint_kind (kind)
    2767        22530 : {}
    2768              : 
    2769       139223 : UintType::UintType (HirId ref, HirId ty_ref, UintKind kind,
    2770       139223 :                     std::set<HirId> refs)
    2771              :   : BaseType (ref, ty_ref, KIND,
    2772       139223 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2773              :               refs),
    2774       278446 :     uint_kind (kind)
    2775       139223 : {}
    2776              : 
    2777              : std::string
    2778      4466218 : UintType::get_name () const
    2779              : {
    2780      4466218 :   return as_string ();
    2781              : }
    2782              : 
    2783              : UintType::UintKind
    2784       953677 : UintType::get_uint_kind () const
    2785              : {
    2786       953677 :   return uint_kind;
    2787              : }
    2788              : 
    2789              : void
    2790          665 : UintType::accept_vis (TyVisitor &vis)
    2791              : {
    2792          665 :   vis.visit (*this);
    2793          665 : }
    2794              : 
    2795              : void
    2796        63332 : UintType::accept_vis (TyConstVisitor &vis) const
    2797              : {
    2798        63332 :   vis.visit (*this);
    2799        63332 : }
    2800              : 
    2801              : std::string
    2802      4700491 : UintType::as_string () const
    2803              : {
    2804      4700491 :   switch (uint_kind)
    2805              :     {
    2806      1263575 :     case U8:
    2807      1263575 :       return "u8";
    2808      1069999 :     case U16:
    2809      1069999 :       return "u16";
    2810      1144444 :     case U32:
    2811      1144444 :       return "u32";
    2812      1176674 :     case U64:
    2813      1176674 :       return "u64";
    2814        45799 :     case U128:
    2815        45799 :       return "u128";
    2816              :     }
    2817            0 :   rust_unreachable ();
    2818              :   return "__unknown_uint_type";
    2819              : }
    2820              : 
    2821              : BaseType *
    2822       139223 : UintType::clone () const
    2823              : {
    2824       139223 :   return new UintType (get_ref (), get_ty_ref (), get_uint_kind (),
    2825       139223 :                        get_combined_refs ());
    2826              : }
    2827              : 
    2828              : bool
    2829        74730 : UintType::is_equal (const BaseType &other) const
    2830              : {
    2831        74730 :   if (!BaseType::is_equal (other))
    2832              :     return false;
    2833              : 
    2834        59960 :   const UintType &o = static_cast<const UintType &> (other);
    2835        59960 :   return get_uint_kind () == o.get_uint_kind ();
    2836              : }
    2837              : 
    2838              : // FloatType
    2839              : 
    2840         9012 : FloatType::FloatType (HirId ref, FloatKind kind, std::set<HirId> refs)
    2841              :   : BaseType (ref, ref, KIND,
    2842         9012 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2843              :               refs),
    2844        18024 :     float_kind (kind)
    2845         9012 : {}
    2846              : 
    2847        45099 : FloatType::FloatType (HirId ref, HirId ty_ref, FloatKind kind,
    2848        45099 :                       std::set<HirId> refs)
    2849              :   : BaseType (ref, ty_ref, KIND,
    2850        45099 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2851              :               refs),
    2852        90198 :     float_kind (kind)
    2853        45099 : {}
    2854              : 
    2855              : std::string
    2856      1000393 : FloatType::get_name () const
    2857              : {
    2858      1000393 :   return as_string ();
    2859              : }
    2860              : 
    2861              : FloatType::FloatKind
    2862       107566 : FloatType::get_float_kind () const
    2863              : {
    2864       107566 :   return float_kind;
    2865              : }
    2866              : 
    2867              : void
    2868          188 : FloatType::accept_vis (TyVisitor &vis)
    2869              : {
    2870          188 :   vis.visit (*this);
    2871          188 : }
    2872              : 
    2873              : void
    2874        16623 : FloatType::accept_vis (TyConstVisitor &vis) const
    2875              : {
    2876        16623 :   vis.visit (*this);
    2877        16623 : }
    2878              : 
    2879              : std::string
    2880      1059546 : FloatType::as_string () const
    2881              : {
    2882      1059546 :   switch (float_kind)
    2883              :     {
    2884       534165 :     case F32:
    2885       534165 :       return "f32";
    2886       525381 :     case F64:
    2887       525381 :       return "f64";
    2888              :     }
    2889            0 :   rust_unreachable ();
    2890              :   return "__unknown_float_type";
    2891              : }
    2892              : 
    2893              : BaseType *
    2894        45099 : FloatType::clone () const
    2895              : {
    2896        45099 :   return new FloatType (get_ref (), get_ty_ref (), get_float_kind (),
    2897        45099 :                         get_combined_refs ());
    2898              : }
    2899              : 
    2900              : bool
    2901        11831 : FloatType::is_equal (const BaseType &other) const
    2902              : {
    2903        11831 :   if (!BaseType::is_equal (other))
    2904              :     return false;
    2905              : 
    2906         9975 :   const FloatType &o = static_cast<const FloatType &> (other);
    2907         9975 :   return get_float_kind () == o.get_float_kind ();
    2908              : }
    2909              : 
    2910              : // UsizeType
    2911              : 
    2912         4506 : USizeType::USizeType (HirId ref, std::set<HirId> refs)
    2913              :   : BaseType (ref, ref, KIND,
    2914         4506 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2915         9012 :               refs)
    2916         4506 : {}
    2917              : 
    2918        53420 : USizeType::USizeType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    2919              :   : BaseType (ref, ty_ref, KIND,
    2920        53420 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2921       106840 :               refs)
    2922        53420 : {}
    2923              : 
    2924              : std::string
    2925      1848880 : USizeType::get_name () const
    2926              : {
    2927      1848880 :   return as_string ();
    2928              : }
    2929              : 
    2930              : void
    2931          250 : USizeType::accept_vis (TyVisitor &vis)
    2932              : {
    2933          250 :   vis.visit (*this);
    2934          250 : }
    2935              : 
    2936              : void
    2937        36685 : USizeType::accept_vis (TyConstVisitor &vis) const
    2938              : {
    2939        36685 :   vis.visit (*this);
    2940        36685 : }
    2941              : 
    2942              : std::string
    2943      1897203 : USizeType::as_string () const
    2944              : {
    2945      1897203 :   return "usize";
    2946              : }
    2947              : 
    2948              : BaseType *
    2949        53420 : USizeType::clone () const
    2950              : {
    2951        53420 :   return new USizeType (get_ref (), get_ty_ref (), get_combined_refs ());
    2952              : }
    2953              : 
    2954              : // ISizeType
    2955              : 
    2956         4775 : ISizeType::ISizeType (HirId ref, std::set<HirId> refs)
    2957              :   : BaseType (ref, ref, KIND,
    2958         4775 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2959         9550 :               refs)
    2960         4775 : {}
    2961              : 
    2962        58709 : ISizeType::ISizeType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    2963              :   : BaseType (ref, ty_ref, KIND,
    2964        58709 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2965       117418 :               refs)
    2966        58709 : {}
    2967              : 
    2968              : std::string
    2969       624868 : ISizeType::get_name () const
    2970              : {
    2971       624868 :   return as_string ();
    2972              : }
    2973              : 
    2974              : void
    2975           73 : ISizeType::accept_vis (TyVisitor &vis)
    2976              : {
    2977           73 :   vis.visit (*this);
    2978           73 : }
    2979              : 
    2980              : void
    2981        22251 : ISizeType::accept_vis (TyConstVisitor &vis) const
    2982              : {
    2983        22251 :   vis.visit (*this);
    2984        22251 : }
    2985              : 
    2986              : std::string
    2987       644471 : ISizeType::as_string () const
    2988              : {
    2989       644471 :   return "isize";
    2990              : }
    2991              : 
    2992              : BaseType *
    2993        58709 : ISizeType::clone () const
    2994              : {
    2995        58709 :   return new ISizeType (get_ref (), get_ty_ref (), get_combined_refs ());
    2996              : }
    2997              : 
    2998              : // Char Type
    2999              : 
    3000         4506 : CharType::CharType (HirId ref, std::set<HirId> refs)
    3001              :   : BaseType (ref, ref, KIND,
    3002         4506 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3003         9012 :               refs)
    3004         4506 : {}
    3005              : 
    3006         8928 : CharType::CharType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    3007              :   : BaseType (ref, ty_ref, KIND,
    3008         8928 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3009        17856 :               refs)
    3010         8928 : {}
    3011              : 
    3012              : std::string
    3013       203460 : CharType::get_name () const
    3014              : {
    3015       203460 :   return as_string ();
    3016              : }
    3017              : 
    3018              : void
    3019           47 : CharType::accept_vis (TyVisitor &vis)
    3020              : {
    3021           47 :   vis.visit (*this);
    3022           47 : }
    3023              : 
    3024              : void
    3025         5532 : CharType::accept_vis (TyConstVisitor &vis) const
    3026              : {
    3027         5532 :   vis.visit (*this);
    3028         5532 : }
    3029              : 
    3030              : std::string
    3031       207906 : CharType::as_string () const
    3032              : {
    3033       207906 :   return "char";
    3034              : }
    3035              : 
    3036              : BaseType *
    3037         8928 : CharType::clone () const
    3038              : {
    3039         8928 :   return new CharType (get_ref (), get_ty_ref (), get_combined_refs ());
    3040              : }
    3041              : 
    3042              : // Reference Type
    3043              : 
    3044        46250 : ReferenceType::ReferenceType (HirId ref, TyVar base, Mutability mut,
    3045        46250 :                               Region region, std::set<HirId> refs)
    3046              :   : BaseType (ref, ref, KIND,
    3047        46250 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3048              :               std::move (refs)),
    3049        92500 :     base (base), mut (mut), region (region)
    3050        46250 : {}
    3051              : 
    3052        75875 : ReferenceType::ReferenceType (HirId ref, HirId ty_ref, TyVar base,
    3053              :                               Mutability mut, Region region,
    3054        75875 :                               std::set<HirId> refs)
    3055              :   : BaseType (ref, ty_ref, KIND,
    3056        75875 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3057              :               std::move (refs)),
    3058       151750 :     base (base), mut (mut), region (region)
    3059        75875 : {}
    3060              : 
    3061              : Mutability
    3062       212643 : ReferenceType::mutability () const
    3063              : {
    3064       212643 :   return mut;
    3065              : }
    3066              : 
    3067              : bool
    3068       894009 : ReferenceType::is_mutable () const
    3069              : {
    3070       894009 :   return mut == Mutability::Mut;
    3071              : }
    3072              : Region
    3073        76128 : ReferenceType::get_region () const
    3074              : {
    3075        76128 :   return region;
    3076              : }
    3077              : 
    3078              : bool
    3079         1942 : ReferenceType::is_dyn_object () const
    3080              : {
    3081         1942 :   return is_dyn_slice_type () || is_dyn_str_type () || is_dyn_obj_type ();
    3082              : }
    3083              : 
    3084              : bool
    3085        20107 : ReferenceType::is_dyn_slice_type (const TyTy::SliceType **slice) const
    3086              : {
    3087        20107 :   const TyTy::BaseType *element = get_base ()->destructure ();
    3088        20107 :   if (element->get_kind () != TyTy::TypeKind::SLICE)
    3089              :     return false;
    3090          648 :   if (slice == nullptr)
    3091              :     return true;
    3092              : 
    3093          648 :   *slice = static_cast<const TyTy::SliceType *> (element);
    3094          648 :   return true;
    3095              : }
    3096              : 
    3097              : bool
    3098        19502 : ReferenceType::is_dyn_str_type (const TyTy::StrType **str) const
    3099              : {
    3100        19502 :   const TyTy::BaseType *element = get_base ()->destructure ();
    3101        19502 :   if (element->get_kind () != TyTy::TypeKind::STR)
    3102              :     return false;
    3103         4058 :   if (str == nullptr)
    3104              :     return true;
    3105              : 
    3106         4049 :   *str = static_cast<const TyTy::StrType *> (element);
    3107         4049 :   return true;
    3108              : }
    3109              : 
    3110              : bool
    3111        15410 : ReferenceType::is_dyn_obj_type (const TyTy::DynamicObjectType **dyn) const
    3112              : {
    3113        15410 :   const TyTy::BaseType *element = get_base ()->destructure ();
    3114        15410 :   if (element->get_kind () != TyTy::TypeKind::DYNAMIC)
    3115              :     return false;
    3116          556 :   if (dyn == nullptr)
    3117              :     return true;
    3118              : 
    3119          549 :   *dyn = static_cast<const TyTy::DynamicObjectType *> (element);
    3120          549 :   return true;
    3121              : }
    3122              : 
    3123              : void
    3124        10210 : ReferenceType::accept_vis (TyVisitor &vis)
    3125              : {
    3126        10210 :   vis.visit (*this);
    3127        10210 : }
    3128              : 
    3129              : void
    3130        19409 : ReferenceType::accept_vis (TyConstVisitor &vis) const
    3131              : {
    3132        19409 :   vis.visit (*this);
    3133        19409 : }
    3134              : 
    3135              : std::string
    3136        71103 : ReferenceType::as_string () const
    3137              : {
    3138       280868 :   return std::string ("&") + (is_mutable () ? "mut" : "") + " "
    3139       142206 :          + get_base ()->as_string ();
    3140              : }
    3141              : 
    3142              : std::string
    3143       780617 : ReferenceType::get_name () const
    3144              : {
    3145      3085195 :   return std::string ("&") + (is_mutable () ? "mut" : "") + " "
    3146      1561234 :          + get_base ()->get_name ();
    3147              : }
    3148              : 
    3149              : bool
    3150        36363 : ReferenceType::is_equal (const BaseType &other) const
    3151              : {
    3152        36363 :   if (get_kind () != other.get_kind ())
    3153              :     return false;
    3154              : 
    3155        35730 :   auto other2 = static_cast<const ReferenceType &> (other);
    3156        35730 :   if (mutability () != other2.mutability ())
    3157              :     return false;
    3158              : 
    3159        32482 :   return get_base ()->is_equal (*other2.get_base ());
    3160        35730 : }
    3161              : 
    3162              : BaseType *
    3163      1318989 : ReferenceType::get_base () const
    3164              : {
    3165      1318989 :   return base.get_tyty ();
    3166              : }
    3167              : 
    3168              : const TyVar &
    3169         1438 : ReferenceType::get_var_element_type () const
    3170              : {
    3171         1438 :   return base;
    3172              : }
    3173              : 
    3174              : BaseType *
    3175        75596 : ReferenceType::clone () const
    3176              : {
    3177        75596 :   return new ReferenceType (get_ref (), get_ty_ref (), base, mutability (),
    3178        75596 :                             get_region (), get_combined_refs ());
    3179              : }
    3180              : 
    3181              : ReferenceType *
    3182         9957 : ReferenceType::handle_substitions (SubstitutionArgumentMappings &mappings)
    3183              : {
    3184         9957 :   auto &mappings_table = Analysis::Mappings::get ();
    3185              : 
    3186         9957 :   ReferenceType *ref = static_cast<ReferenceType *> (clone ());
    3187         9957 :   ref->set_ty_ref (mappings_table.get_next_hir_id ());
    3188              : 
    3189              :   // might be &T or &ADT so this needs to be recursive
    3190         9957 :   auto base = ref->get_base ();
    3191         9957 :   BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings);
    3192         9957 :   ref->base = TyVar::subst_covariant_var (base, concrete);
    3193              : 
    3194         9957 :   return ref;
    3195              : }
    3196              : 
    3197              : // PointerType
    3198              : 
    3199        13852 : PointerType::PointerType (HirId ref, TyVar base, Mutability mut,
    3200        13852 :                           std::set<HirId> refs)
    3201              :   : BaseType (ref, ref, KIND,
    3202        13852 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3203              :               refs),
    3204        27704 :     base (base), mut (mut)
    3205        13852 : {}
    3206              : 
    3207        17180 : PointerType::PointerType (HirId ref, HirId ty_ref, TyVar base, Mutability mut,
    3208        17180 :                           std::set<HirId> refs)
    3209              :   : BaseType (ref, ty_ref, KIND,
    3210        17180 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3211              :               refs),
    3212        34360 :     base (base), mut (mut)
    3213        17180 : {}
    3214              : 
    3215              : Mutability
    3216        64793 : PointerType::mutability () const
    3217              : {
    3218        64793 :   return mut;
    3219              : }
    3220              : 
    3221              : bool
    3222       205866 : PointerType::is_mutable () const
    3223              : {
    3224       205866 :   return mut == Mutability::Mut;
    3225              : }
    3226              : 
    3227              : bool
    3228            0 : PointerType::is_const () const
    3229              : {
    3230            0 :   return mut == Mutability::Imm;
    3231              : }
    3232              : 
    3233              : bool
    3234         4038 : PointerType::is_dyn_object () const
    3235              : {
    3236         4038 :   return is_dyn_slice_type () || is_dyn_str_type () || is_dyn_obj_type ();
    3237              : }
    3238              : 
    3239              : bool
    3240        14217 : PointerType::is_dyn_slice_type (const TyTy::SliceType **slice) const
    3241              : {
    3242        14217 :   const TyTy::BaseType *element = get_base ()->destructure ();
    3243        14217 :   if (element->get_kind () != TyTy::TypeKind::SLICE)
    3244              :     return false;
    3245          533 :   if (slice == nullptr)
    3246              :     return true;
    3247              : 
    3248          533 :   *slice = static_cast<const TyTy::SliceType *> (element);
    3249          533 :   return true;
    3250              : }
    3251              : 
    3252              : bool
    3253        13684 : PointerType::is_dyn_str_type (const TyTy::StrType **str) const
    3254              : {
    3255        13684 :   const TyTy::BaseType *element = get_base ()->destructure ();
    3256        13684 :   if (element->get_kind () != TyTy::TypeKind::STR)
    3257              :     return false;
    3258         2582 :   if (str == nullptr)
    3259              :     return true;
    3260              : 
    3261         2582 :   *str = static_cast<const TyTy::StrType *> (element);
    3262         2582 :   return true;
    3263              : }
    3264              : 
    3265              : bool
    3266        11102 : PointerType::is_dyn_obj_type (const TyTy::DynamicObjectType **dyn) const
    3267              : {
    3268        11102 :   const TyTy::BaseType *element = get_base ()->destructure ();
    3269        11102 :   if (element->get_kind () != TyTy::TypeKind::DYNAMIC)
    3270              :     return false;
    3271            0 :   if (dyn == nullptr)
    3272              :     return true;
    3273              : 
    3274            0 :   *dyn = static_cast<const TyTy::DynamicObjectType *> (element);
    3275            0 :   return true;
    3276              : }
    3277              : 
    3278              : void
    3279         3149 : PointerType::accept_vis (TyVisitor &vis)
    3280              : {
    3281         3149 :   vis.visit (*this);
    3282         3149 : }
    3283              : 
    3284              : void
    3285        11326 : PointerType::accept_vis (TyConstVisitor &vis) const
    3286              : {
    3287        11326 :   vis.visit (*this);
    3288        11326 : }
    3289              : 
    3290              : std::string
    3291        14304 : PointerType::as_string () const
    3292              : {
    3293        53614 :   return std::string ("* ") + (is_mutable () ? "mut" : "const") + " "
    3294        28608 :          + get_base ()->as_string ();
    3295              : }
    3296              : 
    3297              : std::string
    3298       164510 : PointerType::get_name () const
    3299              : {
    3300       630519 :   return std::string ("* ") + (is_mutable () ? "mut" : "const") + " "
    3301       329020 :          + get_base ()->get_name ();
    3302              : }
    3303              : 
    3304              : bool
    3305        16087 : PointerType::is_equal (const BaseType &other) const
    3306              : {
    3307        16087 :   if (get_kind () != other.get_kind ())
    3308              :     return false;
    3309              : 
    3310        15759 :   auto other2 = static_cast<const PointerType &> (other);
    3311        15759 :   if (mutability () != other2.mutability ())
    3312              :     return false;
    3313              : 
    3314        15675 :   return get_base ()->is_equal (*other2.get_base ());
    3315        15759 : }
    3316              : 
    3317              : BaseType *
    3318       324316 : PointerType::get_base () const
    3319              : {
    3320       324316 :   return base.get_tyty ();
    3321              : }
    3322              : 
    3323              : const TyVar &
    3324          653 : PointerType::get_var_element_type () const
    3325              : {
    3326          653 :   return base;
    3327              : }
    3328              : 
    3329              : BaseType *
    3330        16527 : PointerType::clone () const
    3331              : {
    3332        16527 :   return new PointerType (get_ref (), get_ty_ref (), base, mutability (),
    3333        16527 :                           get_combined_refs ());
    3334              : }
    3335              : 
    3336              : PointerType *
    3337         2930 : PointerType::handle_substitions (SubstitutionArgumentMappings &mappings)
    3338              : {
    3339         2930 :   auto &mappings_table = Analysis::Mappings::get ();
    3340              : 
    3341         2930 :   PointerType *ref = static_cast<PointerType *> (clone ());
    3342         2930 :   ref->set_ty_ref (mappings_table.get_next_hir_id ());
    3343              : 
    3344              :   // might be &T or &ADT so this needs to be recursive
    3345         2930 :   auto base = ref->get_base ();
    3346         2930 :   BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings);
    3347         2930 :   ref->base = TyVar::subst_covariant_var (base, concrete);
    3348              : 
    3349         2930 :   return ref;
    3350              : }
    3351              : 
    3352              : // PARAM Type
    3353              : 
    3354        14162 : ParamType::ParamType (std::string symbol, location_t locus, HirId ref,
    3355              :                       std::vector<TypeBoundPredicate> specified_bounds,
    3356        14162 :                       std::set<HirId> refs)
    3357              :   : BaseGeneric (ref, ref, KIND,
    3358        28324 :                  {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, symbol),
    3359              :                   locus},
    3360              :                  specified_bounds, refs),
    3361        42486 :     is_trait_self (false), symbol (symbol)
    3362        14162 : {}
    3363              : 
    3364     85817133 : ParamType::ParamType (bool is_trait_self, std::string symbol, location_t locus,
    3365              :                       HirId ref, HirId ty_ref,
    3366              :                       std::vector<TypeBoundPredicate> specified_bounds,
    3367     85817133 :                       std::set<HirId> refs)
    3368              :   : BaseGeneric (ref, ty_ref, KIND,
    3369    171634266 :                  {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, symbol),
    3370              :                   locus},
    3371              :                  specified_bounds, refs),
    3372    257451399 :     is_trait_self (is_trait_self), symbol (symbol)
    3373     85817133 : {}
    3374              : 
    3375              : bool
    3376      3512781 : ParamType::can_resolve () const
    3377              : {
    3378      3512781 :   return get_ref () != get_ty_ref ();
    3379              : }
    3380              : 
    3381              : void
    3382        60509 : ParamType::accept_vis (TyVisitor &vis)
    3383              : {
    3384        60509 :   vis.visit (*this);
    3385        60509 : }
    3386              : 
    3387              : void
    3388          330 : ParamType::accept_vis (TyConstVisitor &vis) const
    3389              : {
    3390          330 :   vis.visit (*this);
    3391          330 : }
    3392              : 
    3393              : std::string
    3394       165032 : ParamType::as_string () const
    3395              : {
    3396       165032 :   if (!can_resolve ())
    3397              :     {
    3398       115906 :       return get_symbol () + " REF: " + std::to_string (get_ref ());
    3399              :     }
    3400              : 
    3401       107079 :   BaseType *lookup = resolve ();
    3402       214158 :   return get_symbol () + "=" + lookup->as_string ();
    3403              : }
    3404              : 
    3405              : std::string
    3406      1555381 : ParamType::get_name () const
    3407              : {
    3408      1555381 :   if (!can_resolve ())
    3409       758455 :     return get_symbol ();
    3410              : 
    3411       796926 :   return destructure ()->get_name ();
    3412              : }
    3413              : 
    3414              : BaseType *
    3415     85817133 : ParamType::clone () const
    3416              : {
    3417     85817133 :   return new ParamType (is_trait_self, get_symbol (), ident.locus, get_ref (),
    3418              :                         get_ty_ref (), get_specified_bounds (),
    3419    171634266 :                         get_combined_refs ());
    3420              : }
    3421              : 
    3422              : std::string
    3423     87133561 : ParamType::get_symbol () const
    3424              : {
    3425     87133561 :   return symbol;
    3426              : }
    3427              : 
    3428              : BaseType *
    3429      2290681 : ParamType::resolve () const
    3430              : {
    3431      2290681 :   TyVar var (get_ty_ref ());
    3432      2290681 :   BaseType *r = var.get_tyty ();
    3433              : 
    3434      4685701 :   while (r->get_kind () == TypeKind::PARAM)
    3435              :     {
    3436      1655892 :       ParamType *rr = static_cast<ParamType *> (r);
    3437      1655892 :       if (!rr->can_resolve ())
    3438              :         break;
    3439              : 
    3440       104339 :       TyVar v (rr->get_ty_ref ());
    3441       104339 :       BaseType *n = v.get_tyty ();
    3442              : 
    3443              :       // fix infinite loop
    3444       104339 :       if (r == n)
    3445              :         break;
    3446              : 
    3447       104339 :       r = n;
    3448              :     }
    3449              : 
    3450      2290681 :   if (r->get_kind () == TypeKind::PARAM && (r->get_ref () == r->get_ty_ref ()))
    3451      1551553 :     return TyVar (r->get_ty_ref ()).get_tyty ();
    3452              : 
    3453              :   return r;
    3454              : }
    3455              : 
    3456              : bool
    3457        48789 : ParamType::is_equal (const BaseType &other) const
    3458              : {
    3459        48789 :   if (get_kind () != other.get_kind ())
    3460              :     {
    3461        14608 :       if (!can_resolve ())
    3462              :         return false;
    3463              : 
    3464         9992 :       return resolve ()->is_equal (other);
    3465              :     }
    3466              : 
    3467        34181 :   auto other2 = static_cast<const ParamType &> (other);
    3468        34181 :   if (can_resolve () != other2.can_resolve ())
    3469              :     return false;
    3470              : 
    3471        32737 :   if (can_resolve ())
    3472        22776 :     return Resolver::types_compatable (TyTy::TyWithLocation (resolve ()),
    3473        22776 :                                        TyTy::TyWithLocation (other2.resolve ()),
    3474              :                                        UNKNOWN_LOCATION, false, false);
    3475              : 
    3476         9961 :   return get_symbol ().compare (other2.get_symbol ()) == 0;
    3477        34181 : }
    3478              : 
    3479              : ParamType *
    3480        59064 : ParamType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
    3481              : {
    3482        59064 :   SubstitutionArg arg = SubstitutionArg::error ();
    3483        59064 :   bool ok = subst_mappings.get_argument_for_symbol (this, &arg);
    3484        59064 :   if (!ok || arg.is_error ())
    3485        14136 :     return this;
    3486              : 
    3487        44928 :   ParamType *p = static_cast<ParamType *> (clone ());
    3488        44928 :   subst_mappings.on_param_subst (*p, arg);
    3489              : 
    3490        44928 :   const BaseType *resolved = arg.get_tyty ();
    3491        44928 :   if (resolved->get_kind () == TyTy::TypeKind::PARAM)
    3492              :     {
    3493         6312 :       const ParamType &pp = *static_cast<const ParamType *> (resolved);
    3494         6312 :       if (pp.can_resolve ())
    3495         5771 :         pp.resolve ();
    3496              :     }
    3497              : 
    3498              :   // this is the new subst that this needs to pass
    3499        44928 :   p->set_ref (mappings.get_next_hir_id ());
    3500        44928 :   p->set_ty_ref (arg.get_tyty ()->get_ref ());
    3501              : 
    3502        44928 :   return p;
    3503              : }
    3504              : 
    3505              : void
    3506         3688 : ParamType::set_implicit_self_trait ()
    3507              : {
    3508         3688 :   is_trait_self = true;
    3509         3688 : }
    3510              : 
    3511              : bool
    3512        29946 : ParamType::is_implicit_self_trait () const
    3513              : {
    3514        29946 :   return is_trait_self;
    3515              : }
    3516              : 
    3517              : static std::string
    3518        62449 : generate_tree_str (tree value)
    3519              : {
    3520        62449 :   char *buf = nullptr;
    3521        62449 :   size_t size = 0;
    3522              : 
    3523        62449 :   FILE *stream = open_memstream (&buf, &size);
    3524        62449 :   if (!stream)
    3525            0 :     return "<error>";
    3526              : 
    3527        62449 :   print_generic_stmt (stream, value, TDF_NONE);
    3528        62449 :   fclose (stream);
    3529              : 
    3530        62449 :   std::string result = (buf ? std::string (buf, size) : "<error>");
    3531        62449 :   free (buf);
    3532              : 
    3533       124898 :   if (!result.empty () && result.back () == '\n')
    3534        62449 :     result.pop_back ();
    3535              : 
    3536        62449 :   return result;
    3537        62449 : }
    3538              : 
    3539              : // ---
    3540              : 
    3541          807 : ConstParamType::ConstParamType (std::string symbol, location_t locus,
    3542              :                                 BaseType *type, HirId ref, HirId ty_ref,
    3543          807 :                                 std::set<HirId> refs)
    3544              :   : BaseConstType (type),
    3545              :     BaseGeneric (ref, ty_ref, KIND,
    3546         1614 :                  {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, symbol),
    3547              :                   locus},
    3548              :                  {}, refs),
    3549         2421 :     symbol (symbol)
    3550          807 : {}
    3551              : 
    3552              : BaseConstType::ConstKind
    3553         4996 : ConstParamType::const_kind () const
    3554              : {
    3555         4996 :   return BaseConstType::ConstKind::Decl;
    3556              : }
    3557              : 
    3558              : std::string
    3559         2805 : ConstParamType::get_symbol () const
    3560              : {
    3561         2805 :   return symbol;
    3562              : }
    3563              : 
    3564              : bool
    3565         4508 : ConstParamType::can_resolve () const
    3566              : {
    3567         4508 :   return get_ref () != get_ty_ref ();
    3568              : }
    3569              : 
    3570              : BaseType *
    3571         5303 : ConstParamType::resolve () const
    3572              : {
    3573         5303 :   TyVar var (get_ty_ref ());
    3574         5303 :   BaseType *r = var.get_tyty ();
    3575              : 
    3576        10746 :   while (r->get_kind () == TypeKind::CONST)
    3577              :     {
    3578         5443 :       TyVar v (r->get_ty_ref ());
    3579         5443 :       BaseType *n = v.get_tyty ();
    3580              : 
    3581              :       // fix infinite loop
    3582         5443 :       if (r == n)
    3583              :         break;
    3584              : 
    3585          140 :       r = n;
    3586              :     }
    3587              : 
    3588         5303 :   if (r->get_kind () == TypeKind::CONST && (r->get_ref () == r->get_ty_ref ()))
    3589              :     {
    3590         5303 :       auto *const_type = r->as_const_type ();
    3591         5303 :       if (const_type->const_kind () != BaseConstType::ConstKind::Value)
    3592         1461 :         return TyVar (r->get_ty_ref ()).get_tyty ();
    3593              :     }
    3594              : 
    3595              :   return r;
    3596              : }
    3597              : 
    3598              : void
    3599           57 : ConstParamType::accept_vis (TyVisitor &vis)
    3600              : {
    3601           57 :   vis.visit (*this);
    3602           57 : }
    3603              : 
    3604              : void
    3605            0 : ConstParamType::accept_vis (TyConstVisitor &vis) const
    3606              : {
    3607            0 :   vis.visit (*this);
    3608            0 : }
    3609              : 
    3610              : std::string
    3611          165 : ConstParamType::as_string () const
    3612              : {
    3613          165 :   if (!can_resolve ())
    3614              :     {
    3615          330 :       return get_symbol () + " CONST_REF: " + std::to_string (get_ref ());
    3616              :     }
    3617              : 
    3618            0 :   BaseType *lookup = resolve ();
    3619              :   // Avoid infinite recursion if resolve() returns this same type
    3620            0 :   if (lookup == this->as_base_type ())
    3621              :     {
    3622            0 :       return get_symbol () + " CONST_REF: " + std::to_string (get_ref ());
    3623              :     }
    3624              : 
    3625            0 :   return get_symbol () + "=" + lookup->as_string ();
    3626              : }
    3627              : 
    3628              : BaseType *
    3629          682 : ConstParamType::clone () const
    3630              : {
    3631         1364 :   return new ConstParamType (get_symbol (), ident.locus, specified_type,
    3632         1364 :                              get_ref (), get_ty_ref (), get_combined_refs ());
    3633              : }
    3634              : 
    3635              : std::string
    3636         3304 : ConstParamType::get_name () const
    3637              : {
    3638         3304 :   if (!can_resolve ())
    3639          655 :     return get_symbol ();
    3640              : 
    3641         2649 :   BaseType *lookup = resolve ();
    3642         2649 :   if (lookup == this->as_base_type ())
    3643            0 :     return get_symbol () + ":" + get_specified_type ()->get_name ();
    3644              : 
    3645         2649 :   return lookup->get_name ();
    3646              : }
    3647              : 
    3648              : bool
    3649          330 : ConstParamType::is_equal (const BaseType &other) const
    3650              : {
    3651          330 :   if (get_kind () != other.get_kind ())
    3652              :     {
    3653            0 :       if (!can_resolve ())
    3654              :         return false;
    3655              : 
    3656            0 :       return resolve ()->is_equal (other);
    3657              :     }
    3658              : 
    3659          330 :   auto other_const = other.as_const_type ();
    3660          330 :   if (other_const->const_kind () != BaseConstType::ConstKind::Decl)
    3661              :     return false;
    3662              : 
    3663          323 :   auto &other2 = static_cast<const ConstParamType &> (*other_const);
    3664          323 :   if (can_resolve () != other2.can_resolve ())
    3665              :     return false;
    3666              : 
    3667          274 :   if (can_resolve ())
    3668              :     {
    3669              :       // Compare the resolved ty_ref values to avoid infinite recursion
    3670              :       // through types_compatable/unification
    3671          232 :       BaseType *lhs = resolve ();
    3672          232 :       BaseType *rhs = other2.resolve ();
    3673              : 
    3674              :       // If they resolve to the same type (same ty_ref), they're equal
    3675          232 :       if (lhs->get_ty_ref () == rhs->get_ty_ref ())
    3676              :         return true;
    3677              : 
    3678              :       // Otherwise check if the resolved types are equal
    3679              :       // Avoid recursion by checking if we'd be comparing ConstParamTypes again
    3680          199 :       if (lhs->get_kind () == TypeKind::CONST
    3681          199 :           && lhs->as_const_type ()->const_kind ()
    3682              :                == BaseConstType::ConstKind::Decl)
    3683              :         return false; // Would cause recursion, so not equal
    3684              : 
    3685          199 :       return lhs->is_equal (*rhs);
    3686              :     }
    3687              : 
    3688           42 :   return get_symbol ().compare (other2.get_symbol ()) == 0;
    3689              : }
    3690              : 
    3691              : BaseType *
    3692           57 : ConstParamType::handle_substitions (
    3693              :   SubstitutionArgumentMappings &subst_mappings)
    3694              : {
    3695           57 :   SubstitutionArg arg = SubstitutionArg::error ();
    3696           57 :   bool ok = subst_mappings.get_argument_for_symbol (this, &arg);
    3697           57 :   if (!ok || arg.is_error ())
    3698            0 :     return this;
    3699              : 
    3700           57 :   ConstParamType *p = static_cast<ConstParamType *> (clone ());
    3701           57 :   const BaseType *resolved = arg.get_tyty ();
    3702              : 
    3703              :   // this is the new subst that this needs to pass
    3704           57 :   p->set_ref (mappings.get_next_hir_id ());
    3705           57 :   p->set_ty_ref (resolved->get_ref ());
    3706              : 
    3707           57 :   return p;
    3708              : }
    3709              : 
    3710              : // --- ConstValueType
    3711              : 
    3712         2942 : ConstValueType::ConstValueType (tree value, BaseType *type, HirId ref,
    3713         2942 :                                 HirId ty_ref, std::set<HirId> refs)
    3714              :   : BaseType (ref, ty_ref, KIND,
    3715         2942 :               {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
    3716              :               refs),
    3717         5884 :     BaseConstType (type), folded_val (value)
    3718         2942 : {}
    3719              : 
    3720              : BaseConstType::ConstKind
    3721        73611 : ConstValueType::const_kind () const
    3722              : {
    3723        73611 :   return BaseConstType::ConstKind::Value;
    3724              : }
    3725              : 
    3726              : void
    3727            0 : ConstValueType::accept_vis (TyVisitor &vis)
    3728              : {
    3729            0 :   vis.visit (*this);
    3730            0 : }
    3731              : 
    3732              : void
    3733            0 : ConstValueType::accept_vis (TyConstVisitor &vis) const
    3734              : {
    3735            0 :   vis.visit (*this);
    3736            0 : }
    3737              : 
    3738              : std::string
    3739        62449 : ConstValueType::as_string () const
    3740              : {
    3741        62449 :   return generate_tree_str (folded_val);
    3742              : }
    3743              : 
    3744              : BaseType *
    3745          170 : ConstValueType::clone () const
    3746              : {
    3747          340 :   return new ConstValueType (folded_val, specified_type, get_ref (),
    3748          170 :                              get_ty_ref (), get_combined_refs ());
    3749              : }
    3750              : 
    3751              : std::string
    3752         5943 : ConstValueType::get_name () const
    3753              : {
    3754         5943 :   return as_string ();
    3755              : }
    3756              : 
    3757              : bool
    3758         1888 : ConstValueType::is_equal (const BaseType &other) const
    3759              : {
    3760         1888 :   if (get_kind () != other.get_kind ())
    3761              :     return false;
    3762              : 
    3763         1888 :   auto other_const = other.as_const_type ();
    3764         1888 :   if (other_const->const_kind () != BaseConstType::ConstKind::Value)
    3765              :     return false;
    3766              : 
    3767         1805 :   auto &other2 = static_cast<const ConstValueType &> (*other_const);
    3768         1805 :   return folded_val == other2.folded_val;
    3769              : }
    3770              : 
    3771              : tree
    3772         7624 : ConstValueType::get_value () const
    3773              : {
    3774         7624 :   return folded_val;
    3775              : }
    3776              : 
    3777              : // --- ConstInferType
    3778              : 
    3779          106 : ConstInferType::ConstInferType (BaseType *type, HirId ref, HirId ty_ref,
    3780          106 :                                 std::set<HirId> refs)
    3781              :   : BaseType (ref, ty_ref, KIND,
    3782          106 :               {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
    3783              :               refs),
    3784          212 :     BaseConstType (type)
    3785          106 : {}
    3786              : 
    3787              : BaseConstType::ConstKind
    3788         1026 : ConstInferType::const_kind () const
    3789              : {
    3790         1026 :   return BaseConstType::ConstKind::Infer;
    3791              : }
    3792              : 
    3793              : void
    3794            0 : ConstInferType::accept_vis (TyVisitor &vis)
    3795              : {
    3796            0 :   vis.visit (*this);
    3797            0 : }
    3798              : 
    3799              : void
    3800            0 : ConstInferType::accept_vis (TyConstVisitor &vis) const
    3801              : {
    3802            0 :   vis.visit (*this);
    3803            0 : }
    3804              : 
    3805              : std::string
    3806          338 : ConstInferType::as_string () const
    3807              : {
    3808          676 :   return specified_type->get_name () + "-?";
    3809              : }
    3810              : 
    3811              : BaseType *
    3812            0 : ConstInferType::clone () const
    3813              : {
    3814            0 :   auto &mappings = Analysis::Mappings::get ();
    3815            0 :   auto context = Resolver::TypeCheckContext::get ();
    3816              : 
    3817            0 :   ConstInferType *clone
    3818            0 :     = new ConstInferType (specified_type, mappings.get_next_hir_id (),
    3819            0 :                           get_ty_ref (), get_combined_refs ());
    3820              : 
    3821            0 :   context->insert_type (Analysis::NodeMapping (mappings.get_current_crate (),
    3822              :                                                UNKNOWN_NODEID,
    3823              :                                                clone->get_ref (),
    3824            0 :                                                UNKNOWN_LOCAL_DEFID),
    3825              :                         clone);
    3826            0 :   mappings.insert_location (clone->get_ref (),
    3827              :                             mappings.lookup_location (get_ref ()));
    3828              : 
    3829            0 :   clone->append_reference (get_ref ());
    3830              : 
    3831            0 :   return clone;
    3832              : }
    3833              : 
    3834              : std::string
    3835          173 : ConstInferType::get_name () const
    3836              : {
    3837          173 :   return as_string ();
    3838              : }
    3839              : 
    3840              : bool
    3841           46 : ConstInferType::is_equal (const BaseType &other) const
    3842              : {
    3843           46 :   if (get_kind () != other.get_kind ())
    3844              :     return false;
    3845              : 
    3846           46 :   auto other_const = other.as_const_type ();
    3847           46 :   if (other_const->const_kind () != BaseConstType::ConstKind::Infer)
    3848              :     return false;
    3849              : 
    3850            0 :   return get_ref () == other.get_ref ();
    3851              : }
    3852              : 
    3853              : // --- ConstErrorType
    3854              : 
    3855            1 : ConstErrorType::ConstErrorType (BaseType *type, HirId ref, HirId ty_ref,
    3856            1 :                                 std::set<HirId> refs)
    3857              :   : BaseType (ref, ty_ref, KIND,
    3858            1 :               {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
    3859              :               refs),
    3860            2 :     BaseConstType (type)
    3861            1 : {}
    3862              : 
    3863              : BaseConstType::ConstKind
    3864            0 : ConstErrorType::const_kind () const
    3865              : {
    3866            0 :   return BaseConstType::ConstKind::Error;
    3867              : }
    3868              : 
    3869              : void
    3870            0 : ConstErrorType::accept_vis (TyVisitor &vis)
    3871              : {
    3872            0 :   vis.visit (*this);
    3873            0 : }
    3874              : 
    3875              : void
    3876            0 : ConstErrorType::accept_vis (TyConstVisitor &vis) const
    3877              : {
    3878            0 :   vis.visit (*this);
    3879            0 : }
    3880              : 
    3881              : std::string
    3882            0 : ConstErrorType::as_string () const
    3883              : {
    3884            0 :   return "<const_error>";
    3885              : }
    3886              : 
    3887              : BaseType *
    3888            0 : ConstErrorType::clone () const
    3889              : {
    3890            0 :   return new ConstErrorType (specified_type, get_ref (), get_ty_ref (),
    3891            0 :                              get_combined_refs ());
    3892              : }
    3893              : 
    3894              : std::string
    3895            0 : ConstErrorType::get_name () const
    3896              : {
    3897            0 :   return as_string ();
    3898              : }
    3899              : 
    3900              : bool
    3901            0 : ConstErrorType::is_equal (const BaseType &other) const
    3902              : {
    3903            0 :   if (get_kind () != other.get_kind ())
    3904              :     return false;
    3905              : 
    3906            0 :   auto other_const = other.as_const_type ();
    3907            0 :   return other_const->const_kind () == BaseConstType::ConstKind::Error;
    3908              : }
    3909              : 
    3910              : // OpaqueType
    3911              : 
    3912           29 : OpaqueType::OpaqueType (location_t locus, HirId ref,
    3913              :                         std::vector<TypeBoundPredicate> specified_bounds,
    3914           29 :                         std::set<HirId> refs)
    3915              :   : BaseType (ref, ref, KIND,
    3916           58 :               {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, "impl"),
    3917              :                locus},
    3918           87 :               specified_bounds, refs)
    3919           29 : {}
    3920              : 
    3921           29 : OpaqueType::OpaqueType (location_t locus, HirId ref, HirId ty_ref,
    3922              :                         std::vector<TypeBoundPredicate> specified_bounds,
    3923           29 :                         std::set<HirId> refs)
    3924              :   : BaseType (ref, ty_ref, KIND,
    3925           58 :               {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, "impl"),
    3926              :                locus},
    3927           87 :               specified_bounds, refs)
    3928           29 : {}
    3929              : 
    3930              : bool
    3931          252 : OpaqueType::can_resolve () const
    3932              : {
    3933          252 :   return get_ref () != get_ty_ref ();
    3934              : }
    3935              : 
    3936              : void
    3937            0 : OpaqueType::accept_vis (TyVisitor &vis)
    3938              : {
    3939            0 :   vis.visit (*this);
    3940            0 : }
    3941              : 
    3942              : void
    3943            0 : OpaqueType::accept_vis (TyConstVisitor &vis) const
    3944              : {
    3945            0 :   vis.visit (*this);
    3946            0 : }
    3947              : 
    3948              : std::string
    3949          112 : OpaqueType::as_string () const
    3950              : {
    3951          112 :   return get_name ();
    3952              : }
    3953              : 
    3954              : std::string
    3955          505 : OpaqueType::get_name () const
    3956              : {
    3957          505 :   return "impl " + raw_bounds_as_name ();
    3958              : }
    3959              : 
    3960              : BaseType *
    3961           29 : OpaqueType::clone () const
    3962              : {
    3963           58 :   return new OpaqueType (ident.locus, get_ref (), get_ty_ref (),
    3964           29 :                          get_specified_bounds (), get_combined_refs ());
    3965              : }
    3966              : 
    3967              : BaseType *
    3968          310 : OpaqueType::resolve () const
    3969              : {
    3970          310 :   TyVar var (get_ty_ref ());
    3971          310 :   return var.get_tyty ();
    3972              : }
    3973              : 
    3974              : bool
    3975           84 : OpaqueType::is_equal (const BaseType &other) const
    3976              : {
    3977           84 :   auto other2 = static_cast<const OpaqueType &> (other);
    3978           84 :   if (can_resolve () != other2.can_resolve ())
    3979              :     return false;
    3980              : 
    3981           56 :   if (num_specified_bounds () != other.num_specified_bounds ())
    3982              :     return false;
    3983              : 
    3984          112 :   for (const auto &pred : specified_bounds)
    3985              :     {
    3986           56 :       bool found = false;
    3987           56 :       for (const auto &opred : other.get_specified_bounds ())
    3988              :         {
    3989           56 :           found = pred.is_equal (opred);
    3990           56 :           if (found)
    3991              :             break;
    3992              :         }
    3993              : 
    3994           56 :       if (!found)
    3995           28 :         return false;
    3996              :     }
    3997              : 
    3998              :   return true;
    3999           84 : }
    4000              : 
    4001              : // StrType
    4002              : 
    4003         4506 : StrType::StrType (HirId ref, std::set<HirId> refs)
    4004              :   : BaseType (ref, ref, KIND,
    4005         4506 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4006         9012 :               refs)
    4007         4506 : {}
    4008              : 
    4009         3720 : StrType::StrType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    4010              :   : BaseType (ref, ty_ref, KIND,
    4011         3720 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4012         7440 :               refs)
    4013         3720 : {}
    4014              : 
    4015              : std::string
    4016        96523 : StrType::get_name () const
    4017              : {
    4018        96523 :   return as_string ();
    4019              : }
    4020              : 
    4021              : BaseType *
    4022         3720 : StrType::clone () const
    4023              : {
    4024         3720 :   return new StrType (get_ref (), get_ty_ref (), get_combined_refs ());
    4025              : }
    4026              : 
    4027              : void
    4028            8 : StrType::accept_vis (TyVisitor &vis)
    4029              : {
    4030            8 :   vis.visit (*this);
    4031            8 : }
    4032              : 
    4033              : void
    4034         4364 : StrType::accept_vis (TyConstVisitor &vis) const
    4035              : {
    4036         4364 :   vis.visit (*this);
    4037         4364 : }
    4038              : 
    4039              : std::string
    4040       103573 : StrType::as_string () const
    4041              : {
    4042       103573 :   return "str";
    4043              : }
    4044              : 
    4045              : bool
    4046        13979 : StrType::is_equal (const BaseType &other) const
    4047              : {
    4048        13979 :   return get_kind () == other.get_kind ();
    4049              : }
    4050              : 
    4051              : // Never Type
    4052              : 
    4053         5576 : NeverType::NeverType (HirId ref, std::set<HirId> refs)
    4054              :   : BaseType (ref, ref, KIND,
    4055         5576 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4056        11152 :               refs)
    4057         5576 : {}
    4058              : 
    4059          704 : NeverType::NeverType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    4060              :   : BaseType (ref, ty_ref, KIND,
    4061          704 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4062         1408 :               refs)
    4063          704 : {}
    4064              : 
    4065              : std::string
    4066        16377 : NeverType::get_name () const
    4067              : {
    4068        16377 :   return as_string ();
    4069              : }
    4070              : 
    4071              : void
    4072            0 : NeverType::accept_vis (TyVisitor &vis)
    4073              : {
    4074            0 :   vis.visit (*this);
    4075            0 : }
    4076              : 
    4077              : void
    4078         4565 : NeverType::accept_vis (TyConstVisitor &vis) const
    4079              : {
    4080         4565 :   vis.visit (*this);
    4081         4565 : }
    4082              : 
    4083              : std::string
    4084        17207 : NeverType::as_string () const
    4085              : {
    4086        17207 :   return "!";
    4087              : }
    4088              : 
    4089              : BaseType *
    4090          704 : NeverType::clone () const
    4091              : {
    4092          704 :   return new NeverType (get_ref (), get_ty_ref (), get_combined_refs ());
    4093              : }
    4094              : 
    4095              : // placeholder type
    4096              : 
    4097          736 : PlaceholderType::PlaceholderType (std::string symbol, DefId id, HirId ref,
    4098          736 :                                   std::set<HirId> refs)
    4099              :   : BaseType (ref, ref, KIND,
    4100          736 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4101              :               refs),
    4102         1472 :     symbol (symbol), defId (id)
    4103          736 : {}
    4104              : 
    4105         3476 : PlaceholderType::PlaceholderType (std::string symbol, DefId id, HirId ref,
    4106         3476 :                                   HirId ty_ref, std::set<HirId> refs)
    4107              :   : BaseType (ref, ty_ref, KIND,
    4108         3476 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4109              :               refs),
    4110         6952 :     symbol (symbol), defId (id)
    4111         3476 : {}
    4112              : 
    4113              : std::string
    4114        57942 : PlaceholderType::get_name () const
    4115              : {
    4116        57942 :   return as_string ();
    4117              : }
    4118              : 
    4119              : std::string
    4120         4944 : PlaceholderType::get_symbol () const
    4121              : {
    4122         4944 :   return symbol;
    4123              : }
    4124              : 
    4125              : void
    4126          481 : PlaceholderType::accept_vis (TyVisitor &vis)
    4127              : {
    4128          481 :   vis.visit (*this);
    4129          481 : }
    4130              : 
    4131              : void
    4132            0 : PlaceholderType::accept_vis (TyConstVisitor &vis) const
    4133              : {
    4134            0 :   vis.visit (*this);
    4135            0 : }
    4136              : 
    4137              : std::string
    4138        62706 : PlaceholderType::as_string () const
    4139              : {
    4140       125412 :   return "<placeholder:" + (can_resolve () ? resolve ()->as_string () : "")
    4141        62706 :          + ">";
    4142              : }
    4143              : 
    4144              : BaseType *
    4145         3476 : PlaceholderType::clone () const
    4146              : {
    4147         6952 :   return new PlaceholderType (get_symbol (), get_def_id (), get_ref (),
    4148         6952 :                               get_ty_ref (), get_combined_refs ());
    4149              : }
    4150              : 
    4151              : void
    4152         3061 : PlaceholderType::set_associated_type (HirId ref)
    4153              : {
    4154         3061 :   auto context = Resolver::TypeCheckContext::get ();
    4155         3061 :   context->insert_associated_type_mapping (get_ty_ref (), ref);
    4156         3061 : }
    4157              : 
    4158              : void
    4159         1191 : PlaceholderType::clear_associated_type ()
    4160              : {
    4161         1191 :   auto context = Resolver::TypeCheckContext::get ();
    4162         1191 :   context->clear_associated_type_mapping (get_ty_ref ());
    4163         1191 : }
    4164              : 
    4165              : bool
    4166       108103 : PlaceholderType::can_resolve () const
    4167              : {
    4168       108103 :   auto context = Resolver::TypeCheckContext::get ();
    4169              : 
    4170       108103 :   BaseType *lookup = nullptr;
    4171       108103 :   HirId mapping;
    4172              : 
    4173       108103 :   if (!context->lookup_associated_type_mapping (get_ty_ref (), &mapping))
    4174              :     return false;
    4175              : 
    4176        24594 :   if (!context->lookup_type (mapping, &lookup))
    4177              :     return false;
    4178              : 
    4179        24594 :   return lookup != nullptr;
    4180              : }
    4181              : 
    4182              : BaseType *
    4183        24594 : PlaceholderType::resolve () const
    4184              : {
    4185        24594 :   auto context = Resolver::TypeCheckContext::get ();
    4186              : 
    4187        24594 :   HirId mapping;
    4188        24594 :   bool ok = context->lookup_associated_type_mapping (get_ty_ref (), &mapping);
    4189        24594 :   rust_assert (ok);
    4190              : 
    4191        24594 :   return TyVar (mapping).get_tyty ();
    4192              : }
    4193              : 
    4194              : bool
    4195         2459 : PlaceholderType::is_equal (const BaseType &other) const
    4196              : {
    4197         2459 :   if (get_kind () != other.get_kind ())
    4198              :     {
    4199         1725 :       if (!can_resolve ())
    4200              :         return false;
    4201              : 
    4202          593 :       return resolve ()->is_equal (other);
    4203              :     }
    4204              : 
    4205          734 :   auto other2 = static_cast<const PlaceholderType &> (other);
    4206          734 :   return get_symbol ().compare (other2.get_symbol ()) == 0;
    4207          734 : }
    4208              : 
    4209              : DefId
    4210         3579 : PlaceholderType::get_def_id () const
    4211              : {
    4212         3579 :   return defId;
    4213              : }
    4214              : 
    4215              : // Projection type
    4216              : 
    4217         1175 : ProjectionType::ProjectionType (
    4218              :   HirId ref, BaseType *base, const Resolver::TraitReference *trait, DefId item,
    4219              :   std::vector<SubstitutionParamMapping> subst_refs,
    4220              :   SubstitutionArgumentMappings generic_arguments,
    4221         1175 :   RegionConstraints region_constraints, std::set<HirId> refs)
    4222              :   : BaseType (ref, ref, KIND,
    4223         1175 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4224              :               std::move (refs)),
    4225              :     SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
    4226              :                      std::move (region_constraints)),
    4227         2350 :     base (base), trait (trait), item (item)
    4228         1175 : {}
    4229              : 
    4230          989 : ProjectionType::ProjectionType (
    4231              :   HirId ref, HirId ty_ref, BaseType *base,
    4232              :   const Resolver::TraitReference *trait, DefId item,
    4233              :   std::vector<SubstitutionParamMapping> subst_refs,
    4234              :   SubstitutionArgumentMappings generic_arguments,
    4235          989 :   RegionConstraints region_constraints, std::set<HirId> refs)
    4236              :   : BaseType (ref, ty_ref, KIND,
    4237          989 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4238              :               refs),
    4239              :     SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
    4240              :                      std::move (region_constraints)),
    4241         1978 :     base (base), trait (trait), item (item)
    4242          989 : {}
    4243              : 
    4244              : std::string
    4245        21441 : ProjectionType::get_name () const
    4246              : {
    4247        21441 :   return as_string ();
    4248              : }
    4249              : 
    4250              : const BaseType *
    4251         7474 : ProjectionType::get () const
    4252              : {
    4253         7474 :   return base;
    4254              : }
    4255              : 
    4256              : BaseType *
    4257        20503 : ProjectionType::get ()
    4258              : {
    4259        20503 :   return base;
    4260              : }
    4261              : 
    4262              : void
    4263          752 : ProjectionType::accept_vis (TyVisitor &vis)
    4264              : {
    4265          752 :   vis.visit (*this);
    4266          752 : }
    4267              : 
    4268              : void
    4269            0 : ProjectionType::accept_vis (TyConstVisitor &vis) const
    4270              : {
    4271            0 :   vis.visit (*this);
    4272            0 : }
    4273              : 
    4274              : std::string
    4275        42593 : ProjectionType::as_string () const
    4276              : {
    4277       127779 :   return "<Projection=" + subst_as_string () + "::" + base->as_string () + ">";
    4278              : }
    4279              : 
    4280              : BaseType *
    4281          989 : ProjectionType::clone () const
    4282              : {
    4283         1978 :   return new ProjectionType (get_ref (), get_ty_ref (), base->clone (), trait,
    4284          989 :                              item, clone_substs (), used_arguments,
    4285         2967 :                              region_constraints, get_combined_refs ());
    4286              : }
    4287              : 
    4288              : ProjectionType *
    4289          752 : ProjectionType::handle_substitions (
    4290              :   SubstitutionArgumentMappings &subst_mappings)
    4291              : {
    4292              :   // // do we really need to substitute this?
    4293              :   // if (base->needs_generic_substitutions () ||
    4294              :   // base->contains_type_parameters
    4295              :   // ())
    4296              :   //   {
    4297              :   //     return this;
    4298              :   //   }
    4299              : 
    4300          752 :   ProjectionType *projection = static_cast<ProjectionType *> (clone ());
    4301          752 :   projection->set_ty_ref (mappings.get_next_hir_id ());
    4302          752 :   projection->used_arguments = subst_mappings;
    4303              : 
    4304          752 :   auto context = Resolver::TypeCheckContext::get ();
    4305          752 :   context->insert_implicit_type (projection->get_ty_ref (), projection);
    4306              : 
    4307         1148 :   for (auto &sub : projection->get_substs ())
    4308              :     {
    4309          396 :       SubstitutionArg arg = SubstitutionArg::error ();
    4310          396 :       bool ok
    4311          396 :         = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg);
    4312          396 :       if (ok)
    4313          382 :         sub.fill_param_ty (subst_mappings, subst_mappings.get_locus ());
    4314              :     }
    4315              : 
    4316          752 :   auto fty = projection->base;
    4317          752 :   bool is_param_ty = fty->get_kind () == TypeKind::PARAM;
    4318          752 :   if (is_param_ty)
    4319              :     {
    4320          245 :       ParamType *p = static_cast<ParamType *> (fty);
    4321              : 
    4322          245 :       SubstitutionArg arg = SubstitutionArg::error ();
    4323          245 :       bool ok = subst_mappings.get_argument_for_symbol (p, &arg);
    4324          245 :       if (ok)
    4325              :         {
    4326          231 :           auto argt = arg.get_tyty ();
    4327          231 :           bool arg_is_param = argt->get_kind () == TyTy::TypeKind::PARAM;
    4328          231 :           bool arg_is_concrete = argt->get_kind () != TyTy::TypeKind::INFER;
    4329              : 
    4330          231 :           if (arg_is_param || arg_is_concrete)
    4331              :             {
    4332          191 :               auto new_field = argt->clone ();
    4333          191 :               new_field->set_ref (fty->get_ref ());
    4334          191 :               projection->base = new_field;
    4335              :             }
    4336              :           else
    4337              :             {
    4338           40 :               fty->set_ty_ref (argt->get_ref ());
    4339              :             }
    4340              :         }
    4341              :     }
    4342          507 :   else if (fty->needs_generic_substitutions () || !fty->is_concrete ())
    4343              :     {
    4344           70 :       BaseType *concrete
    4345           70 :         = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings);
    4346              : 
    4347           70 :       if (concrete == nullptr || concrete->get_kind () == TyTy::TypeKind::ERROR)
    4348              :         {
    4349            0 :           rust_error_at (subst_mappings.get_locus (),
    4350              :                          "Failed to resolve field substitution type: %s",
    4351            0 :                          fty->as_string ().c_str ());
    4352            0 :           return nullptr;
    4353              :         }
    4354              : 
    4355           70 :       projection->base = concrete;
    4356              :     }
    4357              : 
    4358              :   return projection;
    4359              : }
    4360              : 
    4361              : // DynObjectType
    4362              : 
    4363         4207 : DynamicObjectType::DynamicObjectType (
    4364              :   HirId ref, RustIdent ident, std::vector<TypeBoundPredicate> specified_bounds,
    4365         4207 :   std::set<HirId> refs)
    4366         4207 :   : BaseType (ref, ref, KIND, ident, specified_bounds, refs)
    4367         4207 : {}
    4368              : 
    4369          534 : DynamicObjectType::DynamicObjectType (
    4370              :   HirId ref, HirId ty_ref, RustIdent ident,
    4371          534 :   std::vector<TypeBoundPredicate> specified_bounds, std::set<HirId> refs)
    4372          534 :   : BaseType (ref, ty_ref, KIND, ident, specified_bounds, refs)
    4373          534 : {}
    4374              : 
    4375              : void
    4376            0 : DynamicObjectType::accept_vis (TyVisitor &vis)
    4377              : {
    4378            0 :   vis.visit (*this);
    4379            0 : }
    4380              : 
    4381              : void
    4382           10 : DynamicObjectType::accept_vis (TyConstVisitor &vis) const
    4383              : {
    4384           10 :   vis.visit (*this);
    4385           10 : }
    4386              : 
    4387              : std::string
    4388          947 : DynamicObjectType::as_string () const
    4389              : {
    4390         1894 :   return "dyn [" + raw_bounds_as_string () + "]";
    4391              : }
    4392              : 
    4393              : BaseType *
    4394          534 : DynamicObjectType::clone () const
    4395              : {
    4396          534 :   return new DynamicObjectType (get_ref (), get_ty_ref (), ident,
    4397         1068 :                                 specified_bounds, get_combined_refs ());
    4398              : }
    4399              : 
    4400              : std::string
    4401        49028 : DynamicObjectType::get_name () const
    4402              : {
    4403        98056 :   return "dyn [" + raw_bounds_as_name () + "]";
    4404              : }
    4405              : 
    4406              : bool
    4407        14097 : DynamicObjectType::is_equal (const BaseType &other) const
    4408              : {
    4409        14097 :   if (get_kind () != other.get_kind ())
    4410              :     return false;
    4411              : 
    4412         1086 :   if (num_specified_bounds () != other.num_specified_bounds ())
    4413              :     return false;
    4414              : 
    4415         2180 :   for (const auto &pred : specified_bounds)
    4416              :     {
    4417         1094 :       bool found = false;
    4418         1112 :       for (const auto &opred : other.get_specified_bounds ())
    4419              :         {
    4420         1112 :           found = pred.is_equal (opred);
    4421         1112 :           if (found)
    4422              :             break;
    4423              :         }
    4424              : 
    4425         1094 :       if (!found)
    4426        13011 :         return false;
    4427              :     }
    4428              : 
    4429              :   return true;
    4430              : }
    4431              : 
    4432              : const std::vector<
    4433              :   std::pair<const Resolver::TraitItemReference *, const TypeBoundPredicate *>>
    4434          846 : DynamicObjectType::get_object_items () const
    4435              : {
    4436          846 :   std::vector<
    4437              :     std::pair<const Resolver::TraitItemReference *, const TypeBoundPredicate *>>
    4438          846 :     items;
    4439         1704 :   for (const TypeBoundPredicate &bound : get_specified_bounds ())
    4440              :     {
    4441          858 :       const Resolver::TraitReference *trait = bound.get ();
    4442          858 :       std::vector<const Resolver::TraitItemReference *> trait_items;
    4443          858 :       trait->get_trait_items_and_supers (trait_items);
    4444              : 
    4445         2177 :       for (auto &item : trait_items)
    4446              :         {
    4447         1319 :           if (item->get_trait_item_type ()
    4448              :                 == Resolver::TraitItemReference::TraitItemType::FN
    4449         1319 :               && item->is_object_safe ())
    4450         1319 :             items.emplace_back (item, &bound);
    4451              :         }
    4452          858 :     }
    4453          846 :   return items;
    4454              : }
    4455              : 
    4456              : } // namespace TyTy
    4457              : } // namespace Rust
        

Generated by: LCOV version 2.4-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.