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