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