LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-tyty.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 84.9 % 2169 1842
Test Date: 2026-08-22 16:33:35 Functions: 88.0 % 359 316
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        31891 : TypeKindFormat::to_string (TypeKind kind)
      43              : {
      44        31891 :   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        31780 :     case TypeKind::FNDEF:
      71        31780 :       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           25 :     case TypeKind::INT:
      86           25 :       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      1676838 : BaseType::BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
     150              :                     std::set<HirId> refs)
     151      1676838 :   : TypeBoundsMappings ({}), kind (kind), ref (ref), ty_ref (ty_ref),
     152      1676838 :     orig_ref (ref), combined (refs), ident (ident),
     153      3353676 :     mappings (Analysis::Mappings::get ())
     154      1676838 : {}
     155              : 
     156     95132010 : BaseType::BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
     157              :                     std::vector<TypeBoundPredicate> specified_bounds,
     158              :                     std::set<HirId> refs)
     159     95132010 :   : TypeBoundsMappings (specified_bounds), kind (kind), ref (ref),
     160     95132010 :     ty_ref (ty_ref), orig_ref (ref), combined (refs), ident (ident),
     161    190264020 :     mappings (Analysis::Mappings::get ())
     162     95132010 : {}
     163              : 
     164        99034 : BaseType::~BaseType () {}
     165              : 
     166              : HirId
     167    111391763 : BaseType::get_ref () const
     168              : {
     169    111391763 :   return ref;
     170              : }
     171              : 
     172              : void
     173       464330 : BaseType::set_ref (HirId id)
     174              : {
     175       464330 :   if (id != ref)
     176       267477 :     append_reference (ref);
     177       464330 :   ref = id;
     178       464330 : }
     179              : 
     180              : HirId
     181    109234407 : BaseType::get_ty_ref () const
     182              : {
     183    109234407 :   return ty_ref;
     184              : }
     185              : 
     186              : void
     187       487667 : BaseType::set_ty_ref (HirId id)
     188              : {
     189       487667 :   ty_ref = id;
     190       487667 : }
     191              : HirId
     192         6975 : BaseType::get_orig_ref () const
     193              : {
     194         6975 :   return orig_ref;
     195              : }
     196              : 
     197              : bool
     198       262047 : BaseType::is_equal (const BaseType &other) const
     199              : {
     200       262047 :   return get_kind () == other.get_kind ();
     201              : }
     202              : 
     203              : bool
     204       996794 : BaseType::is_unit () const
     205              : {
     206       996794 :   const TyTy::BaseType *x = destructure ();
     207       996794 :   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        12090 :     case TUPLE:
     239        12090 :       {
     240        12090 :         return x->as<const TupleType> ()->num_fields () == 0;
     241              :       }
     242              : 
     243       955950 :     case ADT:
     244       955950 :       {
     245       955950 :         auto adt = x->as<const ADTType> ();
     246       955950 :         if (adt->is_enum ())
     247              :           return false;
     248              : 
     249       990160 :         for (const auto &variant : adt->get_variants ())
     250              :           {
     251       853422 :             if (variant->num_fields () > 0)
     252       996794 :               return false;
     253              :           }
     254              : 
     255              :         return true;
     256              :       }
     257              :     }
     258              :   return false;
     259              : }
     260              : 
     261              : TypeKind
     262    237006846 : BaseType::get_kind () const
     263              : {
     264    237006846 :   return kind;
     265              : }
     266              : 
     267              : std::set<HirId>
     268     96710071 : BaseType::get_combined_refs () const
     269              : {
     270     96710071 :   return combined;
     271              : }
     272              : 
     273              : void
     274      3990637 : BaseType::append_reference (HirId id)
     275              : {
     276      3990637 :   combined.insert (id);
     277      3990637 : }
     278              : 
     279              : const RustIdent &
     280        87308 : BaseType::get_ident () const
     281              : {
     282        87308 :   return ident;
     283              : }
     284              : 
     285              : location_t
     286        37656 : BaseType::get_locus () const
     287              : {
     288        37656 :   return ident.locus;
     289              : }
     290              : 
     291              : // FIXME this is missing locus
     292              : bool
     293        90974 : BaseType::satisfies_bound (const TypeBoundPredicate &predicate, bool emit_error)
     294              : {
     295        90974 :   const Resolver::TraitReference *query = predicate.get ();
     296        99115 :   for (const auto &bound : specified_bounds)
     297              :     {
     298        34881 :       const Resolver::TraitReference *item = bound.get ();
     299        34881 :       if (item->satisfies_bound (*query))
     300        90974 :         return true;
     301              :     }
     302              : 
     303        64234 :   if (destructure ()->is<InferType> ())
     304              :     return true;
     305              : 
     306        63684 :   bool satisfied = false;
     307        63684 :   auto probed = Resolver::TypeBoundsProbe::Probe (this);
     308       171647 :   for (const auto &b : probed)
     309              :     {
     310       163747 :       const Resolver::TraitReference *bound = b.first;
     311       163747 :       if (bound->satisfies_bound (*query))
     312              :         {
     313              :           satisfied = true;
     314              :           break;
     315              :         }
     316              :     }
     317              : 
     318        63684 :   if (!satisfied)
     319              :     return false;
     320              : 
     321       200381 :   for (const auto &b : probed)
     322              :     {
     323       200380 :       const Resolver::TraitReference *bound = b.first;
     324       200380 :       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        55783 :       if (b.second == nullptr)
     330              :         return true;
     331              : 
     332              :       // need to check that associated types can match as well
     333        55783 :       const HIR::ImplBlock &impl = *(b.second);
     334       141285 :       for (const auto &item : impl.get_impl_items ())
     335              :         {
     336        85504 :           bool is_associated_type = item->get_impl_item_type ()
     337        85504 :                                     == HIR::ImplItem::ImplItemType::TYPE_ALIAS;
     338        85504 :           if (!is_associated_type)
     339        85481 :             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        63684 : }
     389              : 
     390              : bool
     391        79467 : BaseType::bounds_compatible (BaseType &other, location_t locus, bool emit_error)
     392              : {
     393        79467 :   std::vector<std::reference_wrapper<const TypeBoundPredicate>>
     394        79467 :     unsatisfied_bounds;
     395       170441 :   for (auto &bound : get_specified_bounds ())
     396              :     {
     397        90974 :       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        79467 :   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        79467 :   return unsatisfied_bounds.size () == 0;
     427        79467 : }
     428              : 
     429              : void
     430        15038 : BaseType::inherit_bounds (const BaseType &other)
     431              : {
     432        15038 :   inherit_bounds (other.get_specified_bounds ());
     433        15038 : }
     434              : 
     435              : void
     436        80296 : BaseType::inherit_bounds (
     437              :   const std::vector<TyTy::TypeBoundPredicate> &specified_bounds)
     438              : {
     439       148686 :   for (auto &bound : specified_bounds)
     440              :     {
     441        68390 :       add_bound (bound);
     442              :     }
     443        80296 : }
     444              : 
     445              : BaseType *
     446        11433 : BaseType::get_root ()
     447              : {
     448        13509 :   TyTy::BaseType *root = this;
     449              : 
     450        13509 :   if (const auto r = root->try_as<const ReferenceType> ())
     451              :     {
     452         1556 :       root = r->get_base ()->get_root ();
     453              :     }
     454        11953 :   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        11654 :   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        11433 :   return root;
     469              : }
     470              : 
     471              : BaseType *
     472      6102370 : BaseType::destructure ()
     473              : {
     474      6102370 :   int recurisve_ops = 0;
     475      6102370 :   BaseType *x = this;
     476      6368784 :   while (true)
     477              :     {
     478      6368784 :       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      6368784 :       if (auto p = x->try_as<ParamType> ())
     489              :         {
     490       471023 :           auto pr = p->resolve ();
     491       471023 :           if (pr == x)
     492              :             return pr;
     493              : 
     494              :           x = pr;
     495              :         }
     496      5897761 :       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      5890402 :       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     10449913 : BaseType::destructure () const
     531              : {
     532     10449913 :   int recurisve_ops = 0;
     533     10449913 :   const BaseType *x = this;
     534     12272773 :   while (true)
     535              :     {
     536     12272773 :       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     12272773 :       if (auto p = x->try_as<const ParamType> ())
     547              :         {
     548      2659405 :           auto pr = p->resolve ();
     549      2659405 :           if (pr == x)
     550              :             return pr;
     551              : 
     552              :           x = pr;
     553              :         }
     554      9613368 :       else if (x->get_kind () == TypeKind::CONST)
     555              :         {
     556        18883 :           auto p = x->as_const_type ();
     557        18883 :           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      9594485 :       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      9594485 :       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         6156 : BaseType::monomorphized_clone () const
     597              : {
     598         6156 :   const TyTy::BaseType *x = destructure ();
     599              : 
     600         6156 :   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         6155 :   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         6077 :   else if (auto ptr = x->try_as<const PointerType> ())
     614              :     {
     615          496 :       TyVar elm = ptr->get_var_element_type ().monomorphized_clone ();
     616          496 :       return new PointerType (ptr->get_ref (), ptr->get_ty_ref (), elm,
     617          496 :                               ptr->mutability (), ptr->get_combined_refs ());
     618              :     }
     619         5581 :   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         5356 :   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         4901 :   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         4901 :   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         4901 :   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         3883 :   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         3666 :       return x->clone ();
     685              :     }
     686              : 
     687              :   rust_unreachable ();
     688              :   return nullptr;
     689              : }
     690              : 
     691              : std::string
     692        31891 : BaseType::mappings_str () const
     693              : {
     694        63782 :   std::string buffer = "Ref: " + std::to_string (get_ref ())
     695        95673 :                        + " TyRef: " + std::to_string (get_ty_ref ());
     696        31891 :   buffer += "[";
     697        48057 :   for (auto &ref : combined)
     698        48498 :     buffer += std::to_string (ref) + ",";
     699        31891 :   buffer += "]";
     700        63782 :   return "(" + buffer + ")";
     701        31891 : }
     702              : 
     703              : std::string
     704     16073912 : BaseType::debug_str () const
     705              : {
     706              :   // return TypeKindFormat::to_string (get_kind ()) + ":" + as_string () + ":"
     707              :   //        + mappings_str () + ":" + bounds_as_string ();
     708     16073912 :   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        21788 : BaseType::contains_infer () const
     720              : {
     721        22528 :   const TyTy::BaseType *x = destructure ();
     722              : 
     723        22528 :   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        21788 :             return infer;
     730              :         }
     731            0 :       return fn->get_return_type ()->contains_infer ();
     732              :     }
     733        22528 :   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        21788 :             return infer;
     740              :         }
     741            9 :       return fn->get_return_type ()->contains_infer ();
     742              :     }
     743        22519 :   else if (auto adt = x->try_as<const ADTType> ())
     744              :     {
     745         3379 :       for (auto &variant : adt->get_variants ())
     746              :         {
     747         2080 :           bool is_num_variant
     748         2080 :             = variant->get_variant_type () == VariantDef::VariantType::NUM;
     749         2080 :           bool is_unit_variant
     750         2080 :             = variant->get_variant_type () == VariantDef::VariantType::UNIT;
     751         2080 :           if (is_num_variant || is_unit_variant)
     752         1034 :             continue;
     753              : 
     754         2966 :           for (auto &field : variant->get_fields ())
     755              :             {
     756         2021 :               const BaseType *field_type = field->get_field_type ();
     757         2021 :               auto infer = (field_type->contains_infer ());
     758         2021 :               if (infer)
     759        21788 :                 return infer;
     760              :             }
     761              :         }
     762              :       return nullptr;
     763              :     }
     764        21119 :   else if (auto arr = x->try_as<const ArrayType> ())
     765              :     {
     766          175 :       auto type_infer = (arr->get_element_type ()->contains_infer ());
     767          175 :       if (type_infer)
     768              :         return type_infer;
     769          174 :       return arr->get_capacity ()->contains_infer ();
     770              :     }
     771        20944 :   else if (auto slice = x->try_as<const SliceType> ())
     772              :     {
     773          115 :       return slice->get_element_type ()->contains_infer ();
     774              :     }
     775        20829 :   else if (auto ptr = x->try_as<const PointerType> ())
     776              :     {
     777          329 :       return ptr->get_base ()->contains_infer ();
     778              :     }
     779        20500 :   else if (auto ref = x->try_as<const ReferenceType> ())
     780              :     {
     781          113 :       return ref->get_base ()->contains_infer ();
     782              :     }
     783        20387 :   else if (auto tuple = x->try_as<const TupleType> ())
     784              :     {
     785         7750 :       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        12699 :   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        12699 :   else if (x->is<InferType> ())
     801              :     {
     802              :       return x;
     803              :     }
     804        10232 :   else if (x->get_kind () == TyTy::TypeKind::CONST)
     805              :     {
     806          174 :       if (x->as_const_type ()->const_kind () == BaseConstType::Infer)
     807              :         {
     808            8 :           return x;
     809              :         }
     810              :     }
     811              : 
     812              :   return nullptr;
     813              : }
     814              : 
     815              : bool
     816      7038201 : BaseType::is_concrete () const
     817              : {
     818      7319509 :   const TyTy::BaseType *x = destructure ();
     819              : 
     820      7319509 :   if (x->is<ParamType> ())
     821              :     {
     822              :       return false;
     823              :     }
     824      6944015 :   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      6925989 :   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      6910118 :   else if (x->is<PlaceholderType> ())
     841              :     {
     842              :       return true;
     843              :     }
     844      6910118 :   else if (auto fn = x->try_as<const FnType> ())
     845              :     {
     846        19600 :       for (const auto &param : fn->get_params ())
     847              :         {
     848        12540 :           if (!param.get_type ()->is_concrete ())
     849      7038201 :             return false;
     850              :         }
     851         7060 :       return fn->get_return_type ()->is_concrete ();
     852              :     }
     853      6901630 :   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      7038201 :             return false;
     859              :         }
     860         4185 :       return fn->get_return_type ()->is_concrete ();
     861              :     }
     862      6897441 :   else if (auto adt = x->try_as<const ADTType> ())
     863              :     {
     864       862680 :       if (adt->is_unit ())
     865       117983 :         return !adt->needs_substitution ();
     866              : 
     867      1576339 :       for (auto &variant : adt->get_variants ())
     868              :         {
     869       890108 :           bool is_num_variant
     870       890108 :             = variant->get_variant_type () == VariantDef::VariantType::NUM;
     871       890108 :           bool is_unit_variant
     872       890108 :             = variant->get_variant_type () == VariantDef::VariantType::UNIT;
     873       890108 :           if (is_num_variant || is_unit_variant)
     874       137976 :             continue;
     875              : 
     876      2391514 :           for (auto &field : variant->get_fields ())
     877              :             {
     878      1697848 :               const BaseType *field_type = field->get_field_type ();
     879      1697848 :               if (!field_type->is_concrete ())
     880      7038201 :                 return false;
     881              :             }
     882              :         }
     883              :       return true;
     884              :     }
     885      6034761 :   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      6019768 :   else if (auto slice = x->try_as<const SliceType> ())
     891              :     {
     892        15876 :       return slice->get_element_type ()->is_concrete ();
     893              :     }
     894      6003892 :   else if (auto ptr = x->try_as<const PointerType> ())
     895              :     {
     896        18527 :       return ptr->get_base ()->is_concrete ();
     897              :     }
     898      5985365 :   else if (auto ref = x->try_as<const ReferenceType> ())
     899              :     {
     900       219789 :       return ref->get_base ()->is_concrete ();
     901              :     }
     902      5765576 :   else if (auto tuple = x->try_as<const TupleType> ())
     903              :     {
     904        21022 :       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      5746890 :   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     17026363 :   else if (x->is<InferType> () || x->is<BoolType> () || x->is<CharType> ()
     918     11562991 :            || x->is<IntType> () || x->is<UintType> () || x->is<FloatType> ()
     919      1898795 :            || x->is<USizeType> () || x->is<ISizeType> () || x->is<NeverType> ()
     920        33508 :            || x->is<StrType> () || x->is<DynamicObjectType> ()
     921      5746638 :            || x->is<ErrorType> ())
     922              :     {
     923              :       return true;
     924              :     }
     925              : 
     926              :   return false;
     927              : }
     928              : 
     929              : bool
     930           32 : BaseType::is_zero_sized () const
     931              : {
     932           32 :   const TyTy::BaseType *x = destructure ();
     933           32 :   switch (x->get_kind ())
     934              :     {
     935              :     // primitives that are always non-zero size
     936              :     case FNPTR:
     937              :     case FNDEF:
     938              :     case SLICE:
     939              :     case POINTER:
     940              :     case REF:
     941              :     case CLOSURE:
     942              :     case INFER:
     943              :     case BOOL:
     944              :     case CHAR:
     945              :     case INT:
     946              :     case UINT:
     947              :     case FLOAT:
     948              :     case USIZE:
     949              :     case ISIZE:
     950              :     case OPAQUE:
     951              :     case STR:
     952              :     case DYNAMIC:
     953              :     case CONST:
     954              :     case PARAM:
     955              :     case PROJECTION:
     956              :     case PLACEHOLDER:
     957              :     case ERROR:
     958              :       return false;
     959              : 
     960            0 :     case NEVER:
     961            0 :       return true;
     962            1 :     case TUPLE:
     963            1 :       {
     964            1 :         const TupleType *tuple_ty = static_cast<const TupleType *> (x);
     965            1 :         return tuple_ty->is_zero_sized ();
     966              :       }
     967            2 :     case ARRAY:
     968            2 :       {
     969            2 :         const ArrayType *array_ty = static_cast<const ArrayType *> (x);
     970            2 :         return array_ty->is_zero_sized ();
     971              :       }
     972            2 :     case ADT:
     973            2 :       {
     974            2 :         const ADTType *adt_ty = static_cast<const ADTType *> (x);
     975            2 :         return adt_ty->is_zero_sized ();
     976              :       }
     977              :     }
     978              :   return false;
     979              : }
     980              : 
     981              : bool
     982       206090 : BaseType::has_substitutions_defined () const
     983              : {
     984       206090 :   const auto x = this;
     985       206090 :   switch (x->get_kind ())
     986              :     {
     987              :     case INFER:
     988              :     case BOOL:
     989              :     case CHAR:
     990              :     case INT:
     991              :     case UINT:
     992              :     case FLOAT:
     993              :     case USIZE:
     994              :     case ISIZE:
     995              :     case NEVER:
     996              :     case STR:
     997              :     case DYNAMIC:
     998              :     case ERROR:
     999              :     case FNPTR:
    1000              :     case ARRAY:
    1001              :     case SLICE:
    1002              :     case POINTER:
    1003              :     case REF:
    1004              :     case TUPLE:
    1005              :     case PARAM:
    1006              :     case PLACEHOLDER:
    1007              :     case CONST:
    1008              :     case OPAQUE:
    1009              :       return false;
    1010              : 
    1011          190 :     case PROJECTION:
    1012          190 :       {
    1013          190 :         const ProjectionType &p = *static_cast<const ProjectionType *> (x);
    1014          190 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (p);
    1015          190 :         return ref.has_substitutions ();
    1016              :       }
    1017        75109 :       break;
    1018              : 
    1019        75109 :     case FNDEF:
    1020        75109 :       {
    1021        75109 :         const FnType &fn = *static_cast<const FnType *> (x);
    1022        75109 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (fn);
    1023        75109 :         return ref.has_substitutions ();
    1024              :       }
    1025       109810 :       break;
    1026              : 
    1027       109810 :     case ADT:
    1028       109810 :       {
    1029       109810 :         const ADTType &adt = *static_cast<const ADTType *> (x);
    1030       109810 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (adt);
    1031       109810 :         return ref.has_substitutions ();
    1032              :       }
    1033            0 :       break;
    1034              : 
    1035            0 :     case CLOSURE:
    1036            0 :       {
    1037            0 :         const ClosureType &closure = *static_cast<const ClosureType *> (x);
    1038            0 :         const SubstitutionRef &ref
    1039              :           = static_cast<const SubstitutionRef &> (closure);
    1040            0 :         return ref.has_substitutions ();
    1041              :       }
    1042              :       break;
    1043              :     }
    1044              : 
    1045              :   return false;
    1046              : }
    1047              : 
    1048              : bool
    1049       123994 : BaseType::needs_generic_substitutions () const
    1050              : {
    1051       123994 :   const TyTy::BaseType *x = destructure ();
    1052       123994 :   switch (x->get_kind ())
    1053              :     {
    1054              :     case INFER:
    1055              :     case BOOL:
    1056              :     case CHAR:
    1057              :     case INT:
    1058              :     case UINT:
    1059              :     case FLOAT:
    1060              :     case USIZE:
    1061              :     case ISIZE:
    1062              :     case NEVER:
    1063              :     case STR:
    1064              :     case DYNAMIC:
    1065              :     case ERROR:
    1066              :     case FNPTR:
    1067              :     case ARRAY:
    1068              :     case SLICE:
    1069              :     case POINTER:
    1070              :     case REF:
    1071              :     case TUPLE:
    1072              :     case PARAM:
    1073              :     case PLACEHOLDER:
    1074              :     case CONST:
    1075              :     case OPAQUE:
    1076              :       return false;
    1077              : 
    1078         1070 :     case PROJECTION:
    1079         1070 :       {
    1080         1070 :         const ProjectionType &p = *static_cast<const ProjectionType *> (x);
    1081         1070 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (p);
    1082         1070 :         return ref.needs_substitution ();
    1083              :       }
    1084        15191 :       break;
    1085              : 
    1086        15191 :     case FNDEF:
    1087        15191 :       {
    1088        15191 :         const FnType &fn = *static_cast<const FnType *> (x);
    1089        15191 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (fn);
    1090        15191 :         return ref.needs_substitution ();
    1091              :       }
    1092        28554 :       break;
    1093              : 
    1094        28554 :     case ADT:
    1095        28554 :       {
    1096        28554 :         const ADTType &adt = *static_cast<const ADTType *> (x);
    1097        28554 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (adt);
    1098        28554 :         return ref.needs_substitution ();
    1099              :       }
    1100           53 :       break;
    1101              : 
    1102           53 :     case CLOSURE:
    1103           53 :       {
    1104           53 :         const ClosureType &closure = *static_cast<const ClosureType *> (x);
    1105           53 :         const SubstitutionRef &ref
    1106              :           = static_cast<const SubstitutionRef &> (closure);
    1107           53 :         return ref.needs_substitution ();
    1108              :       }
    1109              :       break;
    1110              :     }
    1111              : 
    1112              :   return false;
    1113              : }
    1114              : 
    1115              : const SubstitutionArgumentMappings &
    1116          252 : BaseType::get_subst_argument_mappings () const
    1117              : {
    1118          462 :   static auto empty = SubstitutionArgumentMappings::empty ();
    1119          252 :   const TyTy::BaseType *x = destructure ();
    1120          252 :   switch (x->get_kind ())
    1121              :     {
    1122            0 :     case PROJECTION:
    1123            0 :       {
    1124            0 :         const auto &p = *static_cast<const ProjectionType *> (x);
    1125            0 :         const auto &ref = static_cast<const SubstitutionRef &> (p);
    1126            0 :         return ref.get_substitution_arguments ();
    1127              :       }
    1128            0 :       break;
    1129              : 
    1130            0 :     case FNDEF:
    1131            0 :       {
    1132            0 :         const auto &fn = *static_cast<const FnType *> (x);
    1133            0 :         const auto &ref = static_cast<const SubstitutionRef &> (fn);
    1134            0 :         return ref.get_substitution_arguments ();
    1135              :       }
    1136          252 :       break;
    1137              : 
    1138          252 :     case ADT:
    1139          252 :       {
    1140          252 :         const auto &adt = *static_cast<const ADTType *> (x);
    1141          252 :         const auto &ref = static_cast<const SubstitutionRef &> (adt);
    1142          252 :         return ref.get_substitution_arguments ();
    1143              :       }
    1144            0 :       break;
    1145              : 
    1146            0 :     case CLOSURE:
    1147            0 :       {
    1148            0 :         const auto &closure = *static_cast<const ClosureType *> (x);
    1149            0 :         const auto &ref = static_cast<const SubstitutionRef &> (closure);
    1150            0 :         return ref.get_substitution_arguments ();
    1151              :       }
    1152              :       break;
    1153              : 
    1154              :     default:
    1155              :       return empty;
    1156              :     }
    1157              : 
    1158              :   return empty;
    1159              : }
    1160              : 
    1161              : // InferType
    1162              : 
    1163       160539 : InferType::InferType (HirId ref, InferTypeKind infer_kind, TypeHint hint,
    1164              :                       location_t locus, std::set<HirId> refs)
    1165       160539 :   : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), locus},
    1166              :               refs),
    1167       321078 :     infer_kind (infer_kind), default_hint (hint)
    1168       160539 : {}
    1169              : 
    1170            0 : InferType::InferType (HirId ref, HirId ty_ref, InferTypeKind infer_kind,
    1171              :                       TypeHint hint, location_t locus, std::set<HirId> refs)
    1172              :   : BaseType (ref, ty_ref, KIND,
    1173            0 :               {Resolver::CanonicalPath::create_empty (), locus}, refs),
    1174            0 :     infer_kind (infer_kind), default_hint (hint)
    1175            0 : {}
    1176              : 
    1177              : InferType::InferTypeKind
    1178       238556 : InferType::get_infer_kind () const
    1179              : {
    1180       238556 :   return infer_kind;
    1181              : }
    1182              : 
    1183              : std::string
    1184       405277 : InferType::get_name () const
    1185              : {
    1186       405277 :   return as_string ();
    1187              : }
    1188              : 
    1189              : void
    1190            0 : InferType::accept_vis (TyVisitor &vis)
    1191              : {
    1192            0 :   vis.visit (*this);
    1193            0 : }
    1194              : 
    1195              : void
    1196          571 : InferType::accept_vis (TyConstVisitor &vis) const
    1197              : {
    1198          571 :   vis.visit (*this);
    1199          571 : }
    1200              : 
    1201              : std::string
    1202       431707 : InferType::as_string () const
    1203              : {
    1204       431707 :   switch (infer_kind)
    1205              :     {
    1206       307522 :     case GENERAL:
    1207       307522 :       return "T?";
    1208       122004 :     case INTEGRAL:
    1209       122004 :       return "<integer>";
    1210         2181 :     case FLOAT:
    1211         2181 :       return "<float>";
    1212              :     }
    1213            0 :   return "<infer::error>";
    1214              : }
    1215              : 
    1216              : BaseType *
    1217         4135 : InferType::clone () const
    1218              : {
    1219              :   // clones for inference variables are special in that they _must_ exist within
    1220              :   // the type check context and we must ensure we don't loose the chain
    1221              :   // otherwise we will end up in the missing type annotations case
    1222              :   //
    1223              :   // This means we cannot simply take over the same reference we must generate a
    1224              :   // new ref just like the get_implicit_infer_var code then we can setup the
    1225              :   // chain of references accordingly to ensure we don't loose the ability to
    1226              :   // update the inference variables when we solve the type
    1227              : 
    1228         4135 :   auto &mappings = Analysis::Mappings::get ();
    1229         4135 :   auto context = Resolver::TypeCheckContext::get ();
    1230              : 
    1231         4135 :   InferType *clone
    1232              :     = new InferType (mappings.get_next_hir_id (), get_infer_kind (),
    1233         4135 :                      default_hint, get_ident ().locus, get_combined_refs ());
    1234              : 
    1235         4135 :   context->insert_type (Analysis::NodeMapping (mappings.get_current_crate (),
    1236              :                                                UNKNOWN_NODEID,
    1237              :                                                clone->get_ref (),
    1238         4135 :                                                UNKNOWN_LOCAL_DEFID),
    1239              :                         clone);
    1240         4135 :   mappings.insert_location (clone->get_ref (),
    1241              :                             mappings.lookup_location (get_ref ()));
    1242              : 
    1243              :   // setup the chain to reference this
    1244         4135 :   clone->append_reference (get_ref ());
    1245              : 
    1246         4135 :   return clone;
    1247              : }
    1248              : 
    1249              : bool
    1250         1724 : InferType::default_type (BaseType **type) const
    1251              : {
    1252         1724 :   auto context = Resolver::TypeCheckContext::get ();
    1253         1724 :   bool ok = false;
    1254              : 
    1255              :   // NOTE: Calling this error is misleading.
    1256         1724 :   if (default_hint.kind == TypeKind::ERROR)
    1257              :     {
    1258         1724 :       switch (infer_kind)
    1259              :         {
    1260              :         case GENERAL:
    1261              :           return false;
    1262              : 
    1263         1665 :         case INTEGRAL:
    1264         1665 :           {
    1265         1665 :             ok = context->lookup_builtin ("i32", type);
    1266         1665 :             rust_assert (ok);
    1267              :             return ok;
    1268              :           }
    1269              : 
    1270           48 :         case FLOAT:
    1271           48 :           {
    1272           48 :             ok = context->lookup_builtin ("f64", type);
    1273           48 :             rust_assert (ok);
    1274              :             return ok;
    1275              :           }
    1276              :         }
    1277              :       return false;
    1278              :     }
    1279              : 
    1280            0 :   switch (default_hint.kind)
    1281              :     {
    1282            0 :     case ISIZE:
    1283            0 :       ok = context->lookup_builtin ("isize", type);
    1284            0 :       rust_assert (ok);
    1285              :       return ok;
    1286              : 
    1287            0 :     case USIZE:
    1288            0 :       ok = context->lookup_builtin ("usize", type);
    1289            0 :       rust_assert (ok);
    1290              :       return ok;
    1291              : 
    1292            0 :     case INT:
    1293            0 :       switch (default_hint.szhint)
    1294              :         {
    1295            0 :         case TypeHint::SizeHint::S8:
    1296            0 :           ok = context->lookup_builtin ("i8", type);
    1297            0 :           rust_assert (ok);
    1298              :           return ok;
    1299              : 
    1300            0 :         case TypeHint::SizeHint::S16:
    1301            0 :           ok = context->lookup_builtin ("i16", type);
    1302            0 :           rust_assert (ok);
    1303              :           return ok;
    1304              : 
    1305            0 :         case TypeHint::SizeHint::S32:
    1306            0 :           ok = context->lookup_builtin ("i32", type);
    1307            0 :           rust_assert (ok);
    1308              :           return ok;
    1309              : 
    1310            0 :         case TypeHint::SizeHint::S64:
    1311            0 :           ok = context->lookup_builtin ("i64", type);
    1312            0 :           rust_assert (ok);
    1313              :           return ok;
    1314              : 
    1315            0 :         case TypeHint::SizeHint::S128:
    1316            0 :           ok = context->lookup_builtin ("i128", type);
    1317            0 :           rust_assert (ok);
    1318              :           return ok;
    1319              : 
    1320              :         default:
    1321              :           return false;
    1322              :         }
    1323            0 :       break;
    1324              : 
    1325            0 :     case UINT:
    1326            0 :       switch (default_hint.szhint)
    1327              :         {
    1328            0 :         case TypeHint::SizeHint::S8:
    1329            0 :           ok = context->lookup_builtin ("u8", type);
    1330            0 :           rust_assert (ok);
    1331              :           return ok;
    1332              : 
    1333            0 :         case TypeHint::SizeHint::S16:
    1334            0 :           ok = context->lookup_builtin ("u16", type);
    1335            0 :           rust_assert (ok);
    1336              :           return ok;
    1337              : 
    1338            0 :         case TypeHint::SizeHint::S32:
    1339            0 :           ok = context->lookup_builtin ("u32", type);
    1340            0 :           rust_assert (ok);
    1341              :           return ok;
    1342              : 
    1343            0 :         case TypeHint::SizeHint::S64:
    1344            0 :           ok = context->lookup_builtin ("u64", type);
    1345            0 :           rust_assert (ok);
    1346              :           return ok;
    1347              : 
    1348            0 :         case TypeHint::SizeHint::S128:
    1349            0 :           ok = context->lookup_builtin ("u128", type);
    1350            0 :           rust_assert (ok);
    1351              :           return ok;
    1352              : 
    1353              :         default:
    1354              :           return false;
    1355              :         }
    1356            0 :       break;
    1357              : 
    1358            0 :     case TypeKind::FLOAT:
    1359            0 :       switch (default_hint.szhint)
    1360              :         {
    1361            0 :         case TypeHint::SizeHint::S32:
    1362            0 :           ok = context->lookup_builtin ("f32", type);
    1363            0 :           rust_assert (ok);
    1364              :           return ok;
    1365              : 
    1366            0 :         case TypeHint::SizeHint::S64:
    1367            0 :           ok = context->lookup_builtin ("f64", type);
    1368            0 :           rust_assert (ok);
    1369              :           return ok;
    1370              : 
    1371              :         default:
    1372              :           return false;
    1373              :         }
    1374              :       break;
    1375              : 
    1376              :     default:
    1377              :       return false;
    1378              :     }
    1379              : 
    1380              :   return false;
    1381              : }
    1382              : 
    1383              : void
    1384         6330 : InferType::apply_primitive_type_hint (const BaseType &hint)
    1385              : {
    1386         6330 :   switch (hint.get_kind ())
    1387              :     {
    1388         1366 :     case ISIZE:
    1389         1366 :     case USIZE:
    1390         1366 :       infer_kind = INTEGRAL;
    1391         1366 :       default_hint.kind = hint.get_kind ();
    1392         1366 :       break;
    1393              : 
    1394         3704 :     case INT:
    1395         3704 :       {
    1396         3704 :         infer_kind = INTEGRAL;
    1397         3704 :         default_hint.kind = hint.get_kind ();
    1398         3704 :         default_hint.shint = TypeHint::SignedHint::SIGNED;
    1399         3704 :         switch (hint.as<const IntType> ()->get_int_kind ())
    1400              :           {
    1401           95 :           case IntType::I8:
    1402           95 :             default_hint.szhint = TypeHint::SizeHint::S8;
    1403           95 :             break;
    1404           84 :           case IntType::I16:
    1405           84 :             default_hint.szhint = TypeHint::SizeHint::S16;
    1406           84 :             break;
    1407         3427 :           case IntType::I32:
    1408         3427 :             default_hint.szhint = TypeHint::SizeHint::S32;
    1409         3427 :             break;
    1410           84 :           case IntType::I64:
    1411           84 :             default_hint.szhint = TypeHint::SizeHint::S64;
    1412           84 :             break;
    1413           14 :           case IntType::I128:
    1414           14 :             default_hint.szhint = TypeHint::SizeHint::S128;
    1415           14 :             break;
    1416              :           }
    1417              :       }
    1418              :       break;
    1419              : 
    1420         1132 :     case UINT:
    1421         1132 :       {
    1422         1132 :         infer_kind = INTEGRAL;
    1423         1132 :         default_hint.kind = hint.get_kind ();
    1424         1132 :         default_hint.shint = TypeHint::SignedHint::UNSIGNED;
    1425         1132 :         switch (hint.as<const UintType> ()->get_uint_kind ())
    1426              :           {
    1427          480 :           case UintType::U8:
    1428          480 :             default_hint.szhint = TypeHint::SizeHint::S8;
    1429          480 :             break;
    1430          150 :           case UintType::U16:
    1431          150 :             default_hint.szhint = TypeHint::SizeHint::S16;
    1432          150 :             break;
    1433          303 :           case UintType::U32:
    1434          303 :             default_hint.szhint = TypeHint::SizeHint::S32;
    1435          303 :             break;
    1436          178 :           case UintType::U64:
    1437          178 :             default_hint.szhint = TypeHint::SizeHint::S64;
    1438          178 :             break;
    1439           21 :           case UintType::U128:
    1440           21 :             default_hint.szhint = TypeHint::SizeHint::S128;
    1441           21 :             break;
    1442              :           }
    1443              :       }
    1444              :       break;
    1445              : 
    1446          128 :     case TypeKind::FLOAT:
    1447          128 :       {
    1448          128 :         infer_kind = FLOAT;
    1449          128 :         default_hint.shint = TypeHint::SignedHint::SIGNED;
    1450          128 :         default_hint.kind = hint.get_kind ();
    1451          128 :         switch (hint.as<const FloatType> ()->get_float_kind ())
    1452              :           {
    1453           61 :           case FloatType::F32:
    1454           61 :             default_hint.szhint = TypeHint::SizeHint::S32;
    1455           61 :             break;
    1456              : 
    1457           67 :           case FloatType::F64:
    1458           67 :             default_hint.szhint = TypeHint::SizeHint::S64;
    1459           67 :             break;
    1460              :           }
    1461              :       }
    1462              :       break;
    1463              : 
    1464              :     default:
    1465              :       // TODO bool, char, never??
    1466              :       break;
    1467              :     }
    1468         6330 : }
    1469              : 
    1470              : // ErrorType
    1471              : 
    1472       248135 : ErrorType::ErrorType (HirId ref, std::set<HirId> refs)
    1473              :   : BaseType (ref, ref, KIND,
    1474       248135 :               {Resolver::CanonicalPath::create_empty (), UNDEF_LOCATION}, refs)
    1475       248135 : {}
    1476              : 
    1477            5 : ErrorType::ErrorType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    1478              :   : BaseType (ref, ty_ref, KIND,
    1479            5 :               {Resolver::CanonicalPath::create_empty (), UNDEF_LOCATION}, refs)
    1480            5 : {}
    1481              : 
    1482              : std::string
    1483           62 : ErrorType::get_name () const
    1484              : {
    1485           62 :   return as_string ();
    1486              : }
    1487              : 
    1488              : void
    1489            0 : ErrorType::accept_vis (TyVisitor &vis)
    1490              : {
    1491            0 :   vis.visit (*this);
    1492            0 : }
    1493              : 
    1494              : void
    1495            0 : ErrorType::accept_vis (TyConstVisitor &vis) const
    1496              : {
    1497            0 :   vis.visit (*this);
    1498            0 : }
    1499              : 
    1500              : std::string
    1501           68 : ErrorType::as_string () const
    1502              : {
    1503           68 :   return "<tyty::error>";
    1504              : }
    1505              : 
    1506              : BaseType *
    1507            4 : ErrorType::clone () const
    1508              : {
    1509            4 :   return new ErrorType (get_ref (), get_ty_ref (), get_combined_refs ());
    1510              : }
    1511              : 
    1512              : // Struct Field type
    1513              : 
    1514       273042 : StructFieldType::StructFieldType (HirId ref, std::string name, BaseType *ty,
    1515              :                                   location_t locus)
    1516       273042 :   : ref (ref), name (name), ty (ty), locus (locus)
    1517       273042 : {}
    1518              : 
    1519              : HirId
    1520       272220 : StructFieldType::get_ref () const
    1521              : {
    1522       272220 :   return ref;
    1523              : }
    1524              : 
    1525              : std::string
    1526       498139 : StructFieldType::get_name () const
    1527              : {
    1528       498139 :   return name;
    1529              : }
    1530              : 
    1531              : BaseType *
    1532      2477793 : StructFieldType::get_field_type () const
    1533              : {
    1534      2477793 :   return ty;
    1535              : }
    1536              : 
    1537              : void
    1538         6614 : StructFieldType::set_field_type (BaseType *fty)
    1539              : {
    1540         6614 :   ty = fty;
    1541         6614 : }
    1542              : 
    1543              : void
    1544            0 : StructFieldType::debug () const
    1545              : {
    1546            0 :   rust_debug ("%s", as_string ().c_str ());
    1547            0 : }
    1548              : 
    1549              : location_t
    1550         2353 : StructFieldType::get_locus () const
    1551              : {
    1552         2353 :   return locus;
    1553              : }
    1554              : 
    1555              : std::string
    1556        86834 : StructFieldType::as_string () const
    1557              : {
    1558        86834 :   return name + ":" + get_field_type ()->debug_str ();
    1559              : }
    1560              : 
    1561              : bool
    1562        49044 : StructFieldType::is_equal (const StructFieldType &other) const
    1563              : {
    1564        49044 :   bool names_eq = get_name () == other.get_name ();
    1565              : 
    1566        49044 :   TyTy::BaseType *o = other.get_field_type ();
    1567        49044 :   if (auto op = o->try_as<ParamType> ())
    1568         3937 :     o = op->resolve ();
    1569              : 
    1570        49044 :   bool types_eq = get_field_type ()->is_equal (*o);
    1571              : 
    1572        49044 :   return names_eq && types_eq;
    1573              : }
    1574              : 
    1575              : StructFieldType *
    1576       268034 : StructFieldType::clone () const
    1577              : {
    1578       268034 :   return new StructFieldType (get_ref (), get_name (),
    1579       536068 :                               get_field_type ()->clone (), locus);
    1580              : }
    1581              : 
    1582              : StructFieldType *
    1583          613 : StructFieldType::monomorphized_clone () const
    1584              : {
    1585          613 :   return new StructFieldType (get_ref (), get_name (),
    1586         1226 :                               get_field_type ()->monomorphized_clone (), locus);
    1587              : }
    1588              : 
    1589              : // VariantDef
    1590              : 
    1591              : std::string
    1592            6 : VariantDef::variant_type_string (VariantType type)
    1593              : {
    1594            6 :   switch (type)
    1595              :     {
    1596            0 :     case NUM:
    1597            0 :       return "enumeral";
    1598            4 :     case TUPLE:
    1599            4 :       return "tuple";
    1600            2 :     case STRUCT:
    1601            2 :       return "struct";
    1602            0 :     case UNIT:
    1603            0 :       return "unit struct";
    1604              :     }
    1605            0 :   rust_unreachable ();
    1606              :   return "";
    1607              : }
    1608              : 
    1609         3840 : VariantDef::VariantDef (HirId id, DefId defid, std::string identifier,
    1610              :                         RustIdent ident,
    1611              :                         tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant)
    1612         7680 :   : id (id), defid (defid), identifier (identifier), ident (ident),
    1613         7680 :     discriminant (std::move (discriminant))
    1614              : 
    1615              : {
    1616         3840 :   type = VariantType::NUM;
    1617         3840 :   fields = {};
    1618         3840 : }
    1619              : 
    1620       226961 : VariantDef::VariantDef (HirId id, DefId defid, std::string identifier,
    1621              :                         RustIdent ident, VariantType type,
    1622              :                         tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant,
    1623              :                         std::vector<StructFieldType *> fields)
    1624       453922 :   : id (id), defid (defid), identifier (identifier), ident (ident), type (type),
    1625       453922 :     discriminant (std::move (discriminant)), fields (fields)
    1626              : {
    1627       226961 :   rust_assert ((type == VariantType::NUM && fields.empty ())
    1628              :                || (type == VariantType::UNIT && fields.empty ())
    1629              :                || type == VariantType::TUPLE || type == VariantType::STRUCT);
    1630       226961 : }
    1631              : 
    1632              : VariantDef &
    1633        14058 : VariantDef::get_error_node ()
    1634              : {
    1635        14058 :   static VariantDef node
    1636         3106 :     = VariantDef (UNKNOWN_HIRID, UNKNOWN_DEFID, "",
    1637         3106 :                   {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
    1638        23376 :                   tl::nullopt);
    1639              : 
    1640        14058 :   return node;
    1641              : }
    1642              : 
    1643              : bool
    1644         1816 : VariantDef::is_error () const
    1645              : {
    1646         1816 :   return get_id () == UNKNOWN_HIRID;
    1647              : }
    1648              : 
    1649              : HirId
    1650        17673 : VariantDef::get_id () const
    1651              : {
    1652        17673 :   return id;
    1653              : }
    1654              : 
    1655              : DefId
    1656            0 : VariantDef::get_defid () const
    1657              : {
    1658            0 :   return defid;
    1659              : }
    1660              : 
    1661              : VariantDef::VariantType
    1662      1809068 : VariantDef::get_variant_type () const
    1663              : {
    1664      1809068 :   return type;
    1665              : }
    1666              : 
    1667              : bool
    1668            0 : VariantDef::is_data_variant () const
    1669              : {
    1670            0 :   return type != VariantType::NUM;
    1671              : }
    1672              : 
    1673              : bool
    1674        16207 : VariantDef::is_dataless_variant () const
    1675              : {
    1676        16207 :   return type == VariantType::NUM;
    1677              : }
    1678              : 
    1679              : std::string
    1680        16213 : VariantDef::get_identifier () const
    1681              : {
    1682        16213 :   return identifier;
    1683              : }
    1684              : 
    1685              : size_t
    1686      1347847 : VariantDef::num_fields () const
    1687              : {
    1688      1347847 :   return fields.size ();
    1689              : }
    1690              : 
    1691              : StructFieldType *
    1692       279093 : VariantDef::get_field_at_index (size_t index)
    1693              : {
    1694       279093 :   rust_assert (index < fields.size ());
    1695       279093 :   return fields.at (index);
    1696              : }
    1697              : 
    1698              : std::vector<StructFieldType *> &
    1699       775311 : VariantDef::get_fields ()
    1700              : {
    1701       775311 :   return fields;
    1702              : }
    1703              : 
    1704              : bool
    1705        17914 : VariantDef::lookup_field (const std::string &lookup,
    1706              :                           StructFieldType **field_lookup, size_t *index) const
    1707              : {
    1708        17914 :   size_t i = 0;
    1709        88736 :   for (auto &field : fields)
    1710              :     {
    1711        88728 :       if (field->get_name ().compare (lookup) == 0)
    1712              :         {
    1713        17906 :           if (index != nullptr)
    1714        12568 :             *index = i;
    1715              : 
    1716        17906 :           if (field_lookup != nullptr)
    1717        11276 :             *field_lookup = field;
    1718              : 
    1719        17914 :           return true;
    1720              :         }
    1721        70822 :       i++;
    1722              :     }
    1723              :   return false;
    1724              : }
    1725              : 
    1726              : HIR::Expr &
    1727         3608 : VariantDef::get_discriminant ()
    1728              : {
    1729         3608 :   return *discriminant.value ();
    1730              : }
    1731              : 
    1732              : const HIR::Expr &
    1733       104641 : VariantDef::get_discriminant () const
    1734              : {
    1735       104641 :   return *discriminant.value ();
    1736              : }
    1737              : 
    1738              : bool
    1739       241318 : VariantDef::has_discriminant () const
    1740              : {
    1741       241318 :   return discriminant.has_value ();
    1742              : }
    1743              : 
    1744              : std::string
    1745        75910 : VariantDef::as_string () const
    1746              : {
    1747        75910 :   if (type == VariantType::NUM)
    1748        35050 :     return identifier
    1749        35050 :            + (has_discriminant () ? " = " + get_discriminant ().to_string ()
    1750        17525 :                                   : "");
    1751              : 
    1752        58385 :   std::string buffer;
    1753       145219 :   for (size_t i = 0; i < fields.size (); ++i)
    1754              :     {
    1755       173668 :       buffer += fields.at (i)->as_string ();
    1756        86834 :       if ((i + 1) < fields.size ())
    1757        32562 :         buffer += ", ";
    1758              :     }
    1759              : 
    1760        58385 :   if (type == VariantType::TUPLE)
    1761        55350 :     return identifier + " (" + buffer + ")";
    1762              :   else
    1763        61420 :     return identifier + " {" + buffer + "}";
    1764        58385 : }
    1765              : 
    1766              : bool
    1767        54302 : VariantDef::is_equal (const VariantDef &other) const
    1768              : {
    1769        54302 :   if (type != other.type)
    1770              :     return false;
    1771              : 
    1772        54130 :   if (identifier.compare (other.identifier) != 0)
    1773              :     return false;
    1774              : 
    1775        53409 :   if (fields.size () != other.fields.size ())
    1776              :     return false;
    1777              : 
    1778        99083 :   for (size_t i = 0; i < fields.size (); i++)
    1779              :     {
    1780        49044 :       if (!fields.at (i)->is_equal (*other.fields.at (i)))
    1781              :         return false;
    1782              :     }
    1783              : 
    1784              :   return true;
    1785              : }
    1786              : 
    1787              : VariantDef *
    1788       221351 : VariantDef::clone () const
    1789              : {
    1790       221351 :   std::vector<StructFieldType *> cloned_fields;
    1791       489385 :   for (auto &f : fields)
    1792       268034 :     cloned_fields.push_back ((StructFieldType *) f->clone ());
    1793              : 
    1794       221351 :   auto &&discriminant_opt = has_discriminant ()
    1795       221351 :                               ? tl::optional<std::unique_ptr<HIR::Expr>> (
    1796        84745 :                                 get_discriminant ().clone_expr ())
    1797       442702 :                               : tl::nullopt;
    1798              : 
    1799       221351 :   return new VariantDef (id, defid, identifier, ident, type,
    1800       664053 :                          std::move (discriminant_opt), cloned_fields);
    1801       221351 : }
    1802              : 
    1803              : VariantDef *
    1804         2442 : VariantDef::monomorphized_clone () const
    1805              : {
    1806         2442 :   std::vector<StructFieldType *> cloned_fields;
    1807         3055 :   for (auto &f : fields)
    1808          613 :     cloned_fields.push_back ((StructFieldType *) f->monomorphized_clone ());
    1809              : 
    1810         2442 :   auto discriminant_opt = has_discriminant ()
    1811         2442 :                             ? tl::optional<std::unique_ptr<HIR::Expr>> (
    1812         2371 :                               get_discriminant ().clone_expr ())
    1813         2442 :                             : tl::nullopt;
    1814              : 
    1815         2442 :   return new VariantDef (id, defid, identifier, ident, type,
    1816         7326 :                          std::move (discriminant_opt), cloned_fields);
    1817         2442 : }
    1818              : 
    1819              : const RustIdent &
    1820        32330 : VariantDef::get_ident () const
    1821              : {
    1822        32330 :   return ident;
    1823              : }
    1824              : 
    1825              : // ADTType
    1826              : 
    1827            0 : ADTType::ADTType (DefId id, HirId ref, std::string identifier, RustIdent ident,
    1828              :                   ADTKind adt_kind, std::vector<VariantDef *> variants,
    1829              :                   std::vector<SubstitutionParamMapping> subst_refs,
    1830              :                   SubstitutionArgumentMappings generic_arguments,
    1831              :                   RegionConstraints region_constraints, std::set<HirId> refs)
    1832              :   : BaseType (ref, ref, TypeKind::ADT, ident, refs),
    1833              :     SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
    1834              :                      region_constraints),
    1835            0 :     id (id), identifier (identifier), variants (variants), adt_kind (adt_kind)
    1836            0 : {}
    1837              : 
    1838          105 : ADTType::ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
    1839              :                   RustIdent ident, ADTKind adt_kind,
    1840              :                   std::vector<VariantDef *> variants,
    1841              :                   std::vector<SubstitutionParamMapping> subst_refs,
    1842              :                   SubstitutionArgumentMappings generic_arguments,
    1843              :                   RegionConstraints region_constraints, std::set<HirId> refs)
    1844              :   : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
    1845              :     SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
    1846              :                      region_constraints),
    1847          315 :     id (id), identifier (identifier), variants (variants), adt_kind (adt_kind)
    1848          105 : {}
    1849              : 
    1850       174018 : ADTType::ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
    1851              :                   RustIdent ident, ADTKind adt_kind,
    1852              :                   std::vector<VariantDef *> variants,
    1853              :                   std::vector<SubstitutionParamMapping> subst_refs,
    1854              :                   ReprOptions repr,
    1855              :                   SubstitutionArgumentMappings generic_arguments,
    1856              :                   RegionConstraints region_constraints, std::set<HirId> refs)
    1857              :   : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
    1858              :     SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
    1859              :                      region_constraints),
    1860       174018 :     id (id), identifier (identifier), variants (variants), adt_kind (adt_kind),
    1861       348036 :     repr (repr)
    1862       174018 : {}
    1863              : 
    1864              : void
    1865        13757 : ADTType::accept_vis (TyVisitor &vis)
    1866              : {
    1867        13757 :   vis.visit (*this);
    1868        13757 : }
    1869              : 
    1870              : void
    1871        32675 : ADTType::accept_vis (TyConstVisitor &vis) const
    1872              : {
    1873        32675 :   vis.visit (*this);
    1874        32675 : }
    1875              : 
    1876              : std::string
    1877        57346 : ADTType::as_string () const
    1878              : {
    1879        57346 :   std::string variants_buffer;
    1880       133256 :   for (size_t i = 0; i < number_of_variants (); ++i)
    1881              :     {
    1882        75910 :       TyTy::VariantDef *variant = variants.at (i);
    1883       151820 :       variants_buffer += variant->as_string ();
    1884        75910 :       if ((i + 1) < number_of_variants ())
    1885        18588 :         variants_buffer += ", ";
    1886              :     }
    1887              : 
    1888       172038 :   return identifier + subst_as_string () + "{" + variants_buffer + "}";
    1889        57346 : }
    1890              : 
    1891              : bool
    1892        49211 : ADTType::is_equal (const BaseType &other) const
    1893              : {
    1894        49211 :   if (get_kind () != other.get_kind ())
    1895              :     return false;
    1896              : 
    1897        36931 :   auto other2 = other.as<const ADTType> ();
    1898        36931 :   if (get_adt_kind () != other2->get_adt_kind ())
    1899              :     return false;
    1900              : 
    1901        35851 :   if (number_of_variants () != other2->number_of_variants ())
    1902              :     return false;
    1903              : 
    1904        35851 :   if (has_substitutions_defined () != other2->has_substitutions_defined ())
    1905              :     return false;
    1906              : 
    1907        35425 :   if (has_substitutions_defined ())
    1908              :     {
    1909        11362 :       if (get_num_substitutions () != other2->get_num_substitutions ())
    1910              :         return false;
    1911              : 
    1912        22673 :       for (size_t i = 0; i < get_num_substitutions (); i++)
    1913              :         {
    1914        11956 :           const SubstitutionParamMapping &a = substitutions.at (i);
    1915        11956 :           const SubstitutionParamMapping &b = other2->substitutions.at (i);
    1916              : 
    1917        11956 :           const auto &aa = a.get_param_ty ();
    1918        11956 :           const auto &bb = b.get_param_ty ();
    1919        11956 :           if (!aa->is_equal (*bb))
    1920              :             return false;
    1921              :         }
    1922              :     }
    1923              : 
    1924        84819 :   for (size_t i = 0; i < number_of_variants (); i++)
    1925              :     {
    1926        54302 :       const TyTy::VariantDef *a = get_variants ().at (i);
    1927        54302 :       const TyTy::VariantDef *b = other2->get_variants ().at (i);
    1928              : 
    1929        54302 :       if (!a->is_equal (*b))
    1930              :         return false;
    1931              :     }
    1932              : 
    1933              :   return true;
    1934              : }
    1935              : 
    1936              : bool
    1937            2 : ADTType::is_zero_sized () const
    1938              : {
    1939            2 :   auto phantom = Analysis::Mappings::get ().lookup_lang_item (
    1940              :     LangItem::Kind::PHANTOM_DATA);
    1941            2 :   if (phantom.has_value () && phantom.value () == get_id ())
    1942            1 :     return true;
    1943              : 
    1944            1 :   for (auto *variant : get_variants ())
    1945              :     {
    1946            1 :       for (size_t i = 0; i < variant->num_fields (); i++)
    1947              :         {
    1948            1 :           if (!variant->get_field_at_index (i)
    1949              :                  ->get_field_type ()
    1950            1 :                  ->is_zero_sized ())
    1951            2 :             return false;
    1952              :         }
    1953              :     }
    1954              :   return true;
    1955              : }
    1956              : 
    1957              : DefId
    1958       361806 : ADTType::get_id () const
    1959              : {
    1960       361806 :   return id;
    1961              : }
    1962              : 
    1963              : BaseType *
    1964       169908 : ADTType::clone () const
    1965              : {
    1966       169908 :   std::vector<VariantDef *> cloned_variants;
    1967       389443 :   for (auto &variant : variants)
    1968       219535 :     cloned_variants.push_back (variant->clone ());
    1969              : 
    1970       169908 :   return new ADTType (get_id (), get_ref (), get_ty_ref (), identifier, ident,
    1971       169908 :                       get_adt_kind (), cloned_variants, clone_substs (),
    1972       169908 :                       get_repr_options (), used_arguments,
    1973       509724 :                       get_region_constraints (), get_combined_refs ());
    1974       169908 : }
    1975              : 
    1976              : static bool
    1977        17139 : handle_substitions (SubstitutionArgumentMappings &subst_mappings,
    1978              :                     StructFieldType *field)
    1979              : {
    1980        17139 :   auto fty = field->get_field_type ();
    1981        17139 :   if (auto p = fty->try_as<ParamType> ())
    1982              :     {
    1983        13811 :       SubstitutionArg arg = SubstitutionArg::error ();
    1984        13811 :       bool ok = subst_mappings.get_argument_for_symbol (p, &arg);
    1985        13811 :       if (ok)
    1986              :         {
    1987        13774 :           auto argt = arg.get_tyty ();
    1988        13774 :           bool arg_is_param = argt->get_kind () == TyTy::TypeKind::PARAM;
    1989        13774 :           bool arg_is_concrete = argt->get_kind () != TyTy::TypeKind::INFER;
    1990              : 
    1991        13774 :           if (arg_is_param || arg_is_concrete)
    1992              :             {
    1993         5448 :               auto new_field = argt->clone ();
    1994         5448 :               new_field->set_ref (fty->get_ref ());
    1995         5448 :               field->set_field_type (new_field);
    1996              :             }
    1997              :           else
    1998              :             {
    1999         8326 :               field->get_field_type ()->set_ty_ref (argt->get_ref ());
    2000              :             }
    2001              :         }
    2002              :     }
    2003         3328 :   else if (fty->has_substitutions_defined () || !fty->is_concrete ())
    2004              :     {
    2005         1166 :       BaseType *concrete
    2006         1166 :         = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings);
    2007              : 
    2008         1166 :       if (concrete->get_kind () == TyTy::TypeKind::ERROR)
    2009              :         {
    2010            0 :           rust_error_at (subst_mappings.get_locus (),
    2011              :                          "Failed to resolve field substitution type: %s",
    2012            0 :                          fty->as_string ().c_str ());
    2013            0 :           return false;
    2014              :         }
    2015              : 
    2016         1166 :       auto new_field = concrete->clone ();
    2017         1166 :       new_field->set_ref (fty->get_ref ());
    2018         1166 :       field->set_field_type (new_field);
    2019              :     }
    2020              : 
    2021              :   return true;
    2022              : }
    2023              : 
    2024              : ADTType *
    2025        11498 : ADTType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
    2026              : {
    2027        11498 :   auto adt = clone ()->as<ADTType> ();
    2028        11498 :   adt->set_ty_ref (mappings.get_next_hir_id ());
    2029        11498 :   adt->used_arguments = subst_mappings;
    2030              : 
    2031        23833 :   for (auto &sub : adt->get_substs ())
    2032              :     {
    2033        12335 :       SubstitutionArg arg = SubstitutionArg::error ();
    2034        12335 :       bool ok
    2035        12335 :         = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg);
    2036        12335 :       if (ok)
    2037        12278 :         sub.fill_param_ty (subst_mappings, subst_mappings.get_locus ());
    2038              :     }
    2039              : 
    2040        27705 :   for (auto &variant : adt->get_variants ())
    2041              :     {
    2042        16207 :       if (variant->is_dataless_variant ())
    2043         4171 :         continue;
    2044              : 
    2045        29175 :       for (auto &field : variant->get_fields ())
    2046              :         {
    2047        17139 :           bool ok = ::Rust::TyTy::handle_substitions (subst_mappings, field);
    2048        17139 :           if (!ok)
    2049        11498 :             return adt;
    2050              :         }
    2051              :     }
    2052              : 
    2053              :   return adt;
    2054              : }
    2055              : 
    2056              : bool
    2057         2986 : ADTType::contains_unsafe_cell () const
    2058              : {
    2059         2986 :   if (auto unsafe_cell
    2060         2986 :       = mappings.lookup_lang_item (LangItem::Kind::UNSAFE_CELL))
    2061              :     {
    2062            2 :       if (get_id () == *unsafe_cell)
    2063            2 :         return true;
    2064              : 
    2065            0 :       for (auto &variant : get_variants ())
    2066            0 :         for (auto &field : variant->get_fields ())
    2067            0 :           if (field->get_field_type ()->contains_unsafe_cell ())
    2068            2 :             return true;
    2069              :     }
    2070         2984 :   return false;
    2071              : }
    2072              : 
    2073              : // TupleType
    2074              : 
    2075         6193 : TupleType::TupleType (HirId ref, location_t locus, std::vector<TyVar> fields,
    2076              :                       std::set<HirId> refs)
    2077         6193 :   : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), locus},
    2078              :               refs),
    2079        12386 :     fields (fields)
    2080         6193 : {}
    2081              : 
    2082        10572 : TupleType::TupleType (HirId ref, HirId ty_ref, location_t locus,
    2083              :                       std::vector<TyVar> fields, std::set<HirId> refs)
    2084              :   : BaseType (ref, ty_ref, KIND,
    2085        10572 :               {Resolver::CanonicalPath::create_empty (), locus}, refs),
    2086        21144 :     fields (fields)
    2087        10572 : {}
    2088              : 
    2089              : TupleType *
    2090        34602 : TupleType::get_unit_type ()
    2091              : {
    2092        34602 :   static TupleType *ret = nullptr;
    2093        34602 :   if (ret == nullptr)
    2094         9682 :     ret = new TupleType (Analysis::Mappings::get ().get_next_hir_id (),
    2095         9682 :                          BUILTINS_LOCATION);
    2096        34602 :   return ret;
    2097              : }
    2098              : 
    2099              : size_t
    2100       158590 : TupleType::num_fields () const
    2101              : {
    2102       158590 :   return fields.size ();
    2103              : }
    2104              : 
    2105              : const std::vector<TyVar> &
    2106       190492 : TupleType::get_fields () const
    2107              : {
    2108       190492 :   return fields;
    2109              : }
    2110              : 
    2111              : void
    2112          414 : TupleType::accept_vis (TyVisitor &vis)
    2113              : {
    2114          414 :   vis.visit (*this);
    2115          414 : }
    2116              : 
    2117              : void
    2118        17842 : TupleType::accept_vis (TyConstVisitor &vis) const
    2119              : {
    2120        17842 :   vis.visit (*this);
    2121        17842 : }
    2122              : 
    2123              : std::string
    2124        24283 : TupleType::as_string () const
    2125              : {
    2126        24283 :   size_t i = 0;
    2127        24283 :   std::string fields_buffer;
    2128        32057 :   for (const TyVar &field : get_fields ())
    2129              :     {
    2130        15548 :       fields_buffer += field.get_tyty ()->as_string ();
    2131         7774 :       bool has_next = (i + 1) < get_fields ().size ();
    2132         7774 :       fields_buffer += has_next ? ", " : "";
    2133         7774 :       i++;
    2134              :     }
    2135        48566 :   return "(" + fields_buffer + ")";
    2136        24283 : }
    2137              : 
    2138              : std::string
    2139       135358 : TupleType::get_name () const
    2140              : {
    2141       135358 :   size_t i = 0;
    2142       135358 :   std::string fields_buffer;
    2143       157026 :   for (const TyVar &field : get_fields ())
    2144              :     {
    2145        43336 :       fields_buffer += field.get_tyty ()->get_name ();
    2146        21668 :       bool has_next = (i + 1) < get_fields ().size ();
    2147        21668 :       fields_buffer += has_next ? ", " : "";
    2148        21668 :       i++;
    2149              :     }
    2150       270716 :   return "(" + fields_buffer + ")";
    2151       135358 : }
    2152              : 
    2153              : BaseType *
    2154        17237 : TupleType::get_field (size_t index) const
    2155              : {
    2156        17237 :   return fields.at (index).get_tyty ();
    2157              : }
    2158              : 
    2159              : bool
    2160        14772 : TupleType::is_equal (const BaseType &other) const
    2161              : {
    2162        14772 :   if (get_kind () != other.get_kind ())
    2163              :     return false;
    2164              : 
    2165        14736 :   auto other2 = other.as<const TupleType> ();
    2166        14736 :   if (num_fields () != other2->num_fields ())
    2167              :     return false;
    2168              : 
    2169        16786 :   for (size_t i = 0; i < num_fields (); i++)
    2170              :     {
    2171         2222 :       if (!get_field (i)->is_equal (*other2->get_field (i)))
    2172              :         return false;
    2173              :     }
    2174              :   return true;
    2175              : }
    2176              : 
    2177              : bool
    2178            1 : TupleType::is_zero_sized () const
    2179              : {
    2180            1 :   if (num_fields () == 0)
    2181              :     return true;
    2182            0 :   for (size_t i = 0; i < num_fields (); i++)
    2183              :     {
    2184            0 :       if (!get_field (i)->is_zero_sized ())
    2185              :         return false;
    2186              :     }
    2187              :   return true;
    2188              : }
    2189              : 
    2190              : BaseType *
    2191        10117 : TupleType::clone () const
    2192              : {
    2193        10117 :   std::vector<TyVar> cloned_fields;
    2194        19594 :   for (const auto &f : fields)
    2195         9477 :     cloned_fields.push_back (f.clone ());
    2196              : 
    2197        10117 :   return new TupleType (get_ref (), get_ty_ref (), get_ident ().locus,
    2198        20234 :                         cloned_fields, get_combined_refs ());
    2199        10117 : }
    2200              : 
    2201              : TupleType *
    2202          264 : TupleType::handle_substitions (SubstitutionArgumentMappings &mappings)
    2203              : {
    2204          264 :   auto &mappings_table = Analysis::Mappings::get ();
    2205              : 
    2206          264 :   auto tuple = clone ()->as<TupleType> ();
    2207          264 :   tuple->set_ref (mappings_table.get_next_hir_id ());
    2208          264 :   tuple->set_ty_ref (mappings_table.get_next_hir_id ());
    2209              : 
    2210         1031 :   for (size_t i = 0; i < tuple->fields.size (); i++)
    2211              :     {
    2212          503 :       TyVar &field = fields.at (i);
    2213          503 :       if (!field.get_tyty ()->is_concrete ())
    2214              :         {
    2215          318 :           BaseType *concrete
    2216          318 :             = Resolver::SubstMapperInternal::Resolve (field.get_tyty (),
    2217              :                                                       mappings);
    2218          318 :           tuple->fields[i]
    2219          318 :             = TyVar::subst_covariant_var (field.get_tyty (), concrete);
    2220              :         }
    2221              :     }
    2222              : 
    2223          264 :   return tuple;
    2224              : }
    2225              : 
    2226              : bool
    2227           21 : TupleType::contains_unsafe_cell () const
    2228              : {
    2229           21 :   for (auto &field : get_fields ())
    2230            0 :     if (field.get_tyty ()->contains_unsafe_cell ())
    2231           21 :       return true;
    2232              :   return false;
    2233              : }
    2234              : 
    2235              : void
    2236        22963 : FnType::accept_vis (TyVisitor &vis)
    2237              : {
    2238        22963 :   vis.visit (*this);
    2239        22963 : }
    2240              : 
    2241              : void
    2242        17522 : FnType::accept_vis (TyConstVisitor &vis) const
    2243              : {
    2244        17522 :   vis.visit (*this);
    2245        17522 : }
    2246              : 
    2247              : std::string
    2248        97531 : FnType::as_string () const
    2249              : {
    2250        97531 :   std::string params_str = "";
    2251       223699 :   for (auto &param : params)
    2252              :     {
    2253       126168 :       auto &pattern = param.get_pattern ();
    2254       126168 :       auto ty = param.get_type ();
    2255       378504 :       params_str += pattern.to_string () + " " + ty->as_string ();
    2256       126168 :       params_str += ",";
    2257              :     }
    2258              : 
    2259        97531 :   std::string ret_str = type->as_string ();
    2260       292593 :   return "fn" + subst_as_string () + " (" + params_str + ") -> " + ret_str;
    2261        97531 : }
    2262              : 
    2263              : bool
    2264         8708 : FnType::is_equal (const BaseType &other) const
    2265              : {
    2266         8708 :   if (get_kind () != other.get_kind ())
    2267              :     return false;
    2268              : 
    2269         8708 :   auto &other2 = static_cast<const FnType &> (other);
    2270        26124 :   if (get_identifier ().compare (other2.get_identifier ()) != 0)
    2271              :     return false;
    2272              : 
    2273         8708 :   if (!get_return_type ()->is_equal (*other2.get_return_type ()))
    2274              :     return false;
    2275              : 
    2276         7133 :   if (has_substitutions_defined () != other2.has_substitutions_defined ())
    2277              :     return false;
    2278              : 
    2279         4270 :   if (has_substitutions_defined ())
    2280              :     {
    2281          620 :       if (get_num_substitutions () != other2.get_num_substitutions ())
    2282              :         return false;
    2283              : 
    2284              :       const FnType &ofn = static_cast<const FnType &> (other);
    2285          922 :       for (size_t i = 0; i < get_num_substitutions (); i++)
    2286              :         {
    2287          600 :           const SubstitutionParamMapping &a = get_substs ().at (i);
    2288          600 :           const SubstitutionParamMapping &b = ofn.get_substs ().at (i);
    2289              : 
    2290          600 :           const auto *pa = a.get_param_ty ();
    2291          600 :           const auto *pb = b.get_param_ty ();
    2292          600 :           if (!pa->is_equal (*pb))
    2293              :             return false;
    2294              :         }
    2295              :     }
    2296              : 
    2297         3972 :   if (num_params () != other2.num_params ())
    2298              :     return false;
    2299              : 
    2300        10546 :   for (size_t i = 0; i < num_params (); i++)
    2301              :     {
    2302         6575 :       auto lhs = param_at (i).get_type ();
    2303         6575 :       auto rhs = other2.param_at (i).get_type ();
    2304         6575 :       if (!lhs->is_equal (*rhs))
    2305              :         return false;
    2306              :     }
    2307              :   return true;
    2308              : }
    2309              : 
    2310              : BaseType *
    2311        13838 : FnType::clone () const
    2312              : {
    2313        13838 :   std::vector<TyTy::FnParam> cloned_params;
    2314        34210 :   for (auto &p : params)
    2315        20372 :     cloned_params.push_back (p.clone ());
    2316              : 
    2317        27676 :   return new FnType (get_ref (), get_ty_ref (), get_id (), get_identifier (),
    2318        13838 :                      ident, flags, abi, std::move (cloned_params),
    2319        13838 :                      get_return_type ()->clone (), clone_substs (),
    2320              :                      get_substitution_arguments (), get_region_constraints (),
    2321        69190 :                      get_combined_refs ());
    2322        13838 : }
    2323              : 
    2324              : FnType *
    2325        12377 : FnType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
    2326              : {
    2327        12377 :   FnType *fn = static_cast<FnType *> (clone ());
    2328        12377 :   fn->set_ty_ref (mappings.get_next_hir_id ());
    2329        12377 :   fn->used_arguments = subst_mappings;
    2330              : 
    2331        29074 :   for (auto &sub : fn->get_substs ())
    2332              :     {
    2333        16697 :       SubstitutionArg arg = SubstitutionArg::error ();
    2334              : 
    2335        16697 :       bool ok
    2336        16697 :         = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg);
    2337        16697 :       if (ok)
    2338              :         {
    2339        16218 :           sub.fill_param_ty (subst_mappings, subst_mappings.get_locus ());
    2340              :         }
    2341              :     }
    2342              : 
    2343        12377 :   auto fty = fn->get_return_type ();
    2344        12377 :   bool is_param_ty = fty->get_kind () == TypeKind::PARAM;
    2345        12377 :   if (is_param_ty)
    2346              :     {
    2347         3604 :       ParamType *p = static_cast<ParamType *> (fty);
    2348              : 
    2349         3604 :       SubstitutionArg arg = SubstitutionArg::error ();
    2350         3604 :       bool ok = subst_mappings.get_argument_for_symbol (p, &arg);
    2351         3604 :       if (ok)
    2352              :         {
    2353         3597 :           auto argt = arg.get_tyty ();
    2354         3597 :           bool arg_is_param = argt->get_kind () == TyTy::TypeKind::PARAM;
    2355         3597 :           bool arg_is_concrete = argt->get_kind () != TyTy::TypeKind::INFER;
    2356              : 
    2357         3597 :           if (arg_is_param || arg_is_concrete)
    2358              :             {
    2359         1420 :               auto new_field = argt->clone ();
    2360         1420 :               new_field->set_ref (fty->get_ref ());
    2361         1420 :               fn->type = new_field;
    2362              :             }
    2363              :           else
    2364              :             {
    2365         2177 :               fty->set_ty_ref (argt->get_ref ());
    2366              :             }
    2367              :         }
    2368              :     }
    2369         8773 :   else if (fty->needs_generic_substitutions () || !fty->is_concrete ())
    2370              :     {
    2371         3248 :       BaseType *concrete
    2372         3248 :         = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings);
    2373              : 
    2374         3248 :       if (concrete == nullptr || concrete->get_kind () == TyTy::TypeKind::ERROR)
    2375              :         {
    2376            0 :           rust_error_at (subst_mappings.get_locus (),
    2377              :                          "Failed to resolve field substitution type: %s",
    2378            0 :                          fty->as_string ().c_str ());
    2379            0 :           return nullptr;
    2380              :         }
    2381              : 
    2382         3248 :       auto new_field = concrete->clone ();
    2383         3248 :       new_field->set_ref (fty->get_ref ());
    2384         3248 :       fn->type = new_field;
    2385              :     }
    2386              : 
    2387        30501 :   for (auto &param : fn->get_params ())
    2388              :     {
    2389        18124 :       auto fty = param.get_type ();
    2390              : 
    2391        18124 :       bool is_param_ty = fty->get_kind () == TypeKind::PARAM;
    2392        18124 :       if (is_param_ty)
    2393              :         {
    2394         5854 :           ParamType *p = static_cast<ParamType *> (fty);
    2395              : 
    2396         5854 :           SubstitutionArg arg = SubstitutionArg::error ();
    2397         5854 :           bool ok = subst_mappings.get_argument_for_symbol (p, &arg);
    2398         5854 :           if (ok)
    2399              :             {
    2400         5796 :               auto argt = arg.get_tyty ();
    2401         5796 :               bool arg_is_param = argt->get_kind () == TyTy::TypeKind::PARAM;
    2402         5796 :               bool arg_is_concrete = argt->get_kind () != TyTy::TypeKind::INFER;
    2403              : 
    2404         5796 :               if (arg_is_param || arg_is_concrete)
    2405              :                 {
    2406         2127 :                   auto new_field = argt->clone ();
    2407         2127 :                   new_field->set_ref (fty->get_ref ());
    2408         2127 :                   param.set_type (new_field);
    2409              :                 }
    2410              :               else
    2411              :                 {
    2412         3669 :                   fty->set_ty_ref (argt->get_ref ());
    2413              :                 }
    2414              :             }
    2415              :         }
    2416        12270 :       else if (fty->has_substitutions_defined () || !fty->is_concrete ())
    2417              :         {
    2418        11146 :           BaseType *concrete
    2419        11146 :             = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings);
    2420              : 
    2421        11146 :           if (concrete == nullptr
    2422        11146 :               || concrete->get_kind () == TyTy::TypeKind::ERROR)
    2423              :             {
    2424            0 :               rust_error_at (subst_mappings.get_locus (),
    2425              :                              "Failed to resolve field substitution type: %s",
    2426            0 :                              fty->as_string ().c_str ());
    2427            0 :               return nullptr;
    2428              :             }
    2429              : 
    2430        11146 :           auto new_field = concrete->clone ();
    2431        11146 :           new_field->set_ref (fty->get_ref ());
    2432        11146 :           param.set_type (new_field);
    2433              :         }
    2434              :     }
    2435              : 
    2436              :   return fn;
    2437              : }
    2438              : 
    2439              : void
    2440           46 : FnPtr::accept_vis (TyVisitor &vis)
    2441              : {
    2442           46 :   vis.visit (*this);
    2443           46 : }
    2444              : 
    2445              : void
    2446          192 : FnPtr::accept_vis (TyConstVisitor &vis) const
    2447              : {
    2448          192 :   vis.visit (*this);
    2449          192 : }
    2450              : 
    2451              : std::string
    2452         9432 : FnPtr::as_string () const
    2453              : {
    2454         9432 :   std::string params_str;
    2455              : 
    2456         9432 :   auto &params = get_params ();
    2457        10168 :   for (auto &p : params)
    2458              :     {
    2459         2208 :       params_str += p.get_tyty ()->as_string () + " ,";
    2460              :     }
    2461              : 
    2462         9432 :   std::string unsafety = "";
    2463         9432 :   if (get_unsafety () == Unsafety::Unsafe)
    2464         3832 :     unsafety = "unsafe ";
    2465              : 
    2466         9432 :   std::string abi = get_string_from_abi (get_abi ());
    2467        37728 :   return unsafety + "abi:" + abi + " " + "fnptr (" + params_str + ") -> "
    2468        28296 :          + get_return_type ()->as_string ();
    2469         9432 : }
    2470              : 
    2471              : bool
    2472          322 : FnPtr::is_equal (const BaseType &other) const
    2473              : {
    2474          322 :   if (get_kind () != other.get_kind ())
    2475              :     return false;
    2476              : 
    2477          110 :   auto other2 = static_cast<const FnPtr &> (other);
    2478          110 :   auto this_ret_type = get_return_type ();
    2479          110 :   auto other_ret_type = other2.get_return_type ();
    2480          110 :   if (this_ret_type->is_equal (*other_ret_type))
    2481              :     return false;
    2482              : 
    2483           27 :   if (num_params () != other2.num_params ())
    2484              :     return false;
    2485              : 
    2486           27 :   for (size_t i = 0; i < num_params (); i++)
    2487              :     {
    2488            0 :       if (!get_param_type_at (i)->is_equal (*other2.get_param_type_at (i)))
    2489              :         return false;
    2490              :     }
    2491              :   return true;
    2492          110 : }
    2493              : 
    2494              : BaseType *
    2495         1488 : FnPtr::clone () const
    2496              : {
    2497         1488 :   std::vector<TyVar> cloned_params;
    2498         1488 :   cloned_params.reserve (params.size ());
    2499              : 
    2500         1559 :   for (auto &p : params)
    2501           71 :     cloned_params.emplace_back (p.get_ref ());
    2502              : 
    2503         1488 :   return new FnPtr (get_ref (), get_ty_ref (), ident.locus,
    2504              :                     std::move (cloned_params), result_type, get_abi (),
    2505         1488 :                     get_unsafety (), get_combined_refs ());
    2506         1488 : }
    2507              : 
    2508              : FnPtr *
    2509            8 : FnPtr::handle_substitions (SubstitutionArgumentMappings &mappings)
    2510              : {
    2511            8 :   auto &mappings_table = Analysis::Mappings::get ();
    2512              : 
    2513            8 :   auto fn = clone ()->as<FnPtr> ();
    2514            8 :   fn->set_ref (mappings_table.get_next_hir_id ());
    2515            8 :   fn->set_ty_ref (mappings_table.get_next_hir_id ());
    2516              : 
    2517            8 :   if (!fn->result_type.get_tyty ()->is_concrete ())
    2518              :     {
    2519            4 :       BaseType *concrete
    2520            4 :         = Resolver::SubstMapperInternal::Resolve (fn->result_type.get_tyty (),
    2521              :                                                   mappings);
    2522            4 :       fn->result_type
    2523            4 :         = TyVar::subst_covariant_var (fn->result_type.get_tyty (), concrete);
    2524              :     }
    2525              : 
    2526           16 :   for (size_t i = 0; i < fn->params.size (); i++)
    2527              :     {
    2528            8 :       TyVar &field = fn->params.at (i);
    2529            8 :       if (!field.get_tyty ()->is_concrete ())
    2530              :         {
    2531            4 :           BaseType *concrete
    2532            4 :             = Resolver::SubstMapperInternal::Resolve (field.get_tyty (),
    2533              :                                                       mappings);
    2534            4 :           fn->params[i]
    2535            4 :             = TyVar::subst_covariant_var (field.get_tyty (), concrete);
    2536              :         }
    2537              :     }
    2538              : 
    2539            8 :   return fn;
    2540              : }
    2541              : 
    2542              : void
    2543            0 : ClosureType::accept_vis (TyVisitor &vis)
    2544              : {
    2545            0 :   vis.visit (*this);
    2546            0 : }
    2547              : 
    2548              : void
    2549          243 : ClosureType::accept_vis (TyConstVisitor &vis) const
    2550              : {
    2551          243 :   vis.visit (*this);
    2552          243 : }
    2553              : 
    2554              : std::string
    2555         2653 : ClosureType::as_string () const
    2556              : {
    2557         2653 :   std::string params_buf = parameters->as_string ();
    2558         7959 :   return "|" + params_buf + "| {" + result_type.get_tyty ()->as_string () + "}";
    2559         2653 : }
    2560              : 
    2561              : bool
    2562          161 : ClosureType::is_equal (const BaseType &other) const
    2563              : {
    2564          161 :   if (other.get_kind () != TypeKind::CLOSURE)
    2565              :     return false;
    2566              : 
    2567          161 :   const ClosureType &other2 = static_cast<const ClosureType &> (other);
    2568          161 :   if (get_def_id () != other2.get_def_id ())
    2569              :     return false;
    2570              : 
    2571          161 :   if (!get_parameters ().is_equal (other2.get_parameters ()))
    2572              :     return false;
    2573              : 
    2574          161 :   return get_result_type ().is_equal (other2.get_result_type ());
    2575              : }
    2576              : 
    2577              : BaseType *
    2578          657 : ClosureType::clone () const
    2579              : {
    2580          657 :   return new ClosureType (get_ref (), get_ty_ref (), ident, id,
    2581          657 :                           (TyTy::TupleType *) parameters->clone (), result_type,
    2582         1314 :                           clone_substs (), captures, get_combined_refs (),
    2583         2628 :                           specified_bounds);
    2584              : }
    2585              : 
    2586              : ClosureType *
    2587            0 : ClosureType::handle_substitions (SubstitutionArgumentMappings &mappings)
    2588              : {
    2589            0 :   rust_unreachable ();
    2590              :   return nullptr;
    2591              : }
    2592              : 
    2593              : void
    2594          113 : ArrayType::accept_vis (TyVisitor &vis)
    2595              : {
    2596          113 :   vis.visit (*this);
    2597          113 : }
    2598              : 
    2599              : void
    2600         4139 : ArrayType::accept_vis (TyConstVisitor &vis) const
    2601              : {
    2602         4139 :   vis.visit (*this);
    2603         4139 : }
    2604              : 
    2605              : std::string
    2606        57121 : ArrayType::as_string () const
    2607              : {
    2608        57121 :   auto cap = get_capacity ();
    2609        57121 :   std::string capacity_str = cap->as_string ();
    2610              : 
    2611       171363 :   return "[" + get_element_type ()->as_string () + "; " + capacity_str + "]";
    2612        57121 : }
    2613              : 
    2614              : bool
    2615         2415 : ArrayType::is_equal (const BaseType &other) const
    2616              : {
    2617         2415 :   if (get_kind () != other.get_kind ())
    2618              :     return false;
    2619              : 
    2620         2362 :   auto other2 = static_cast<const ArrayType &> (other);
    2621              : 
    2622         2362 :   auto this_element_type = get_element_type ();
    2623         2362 :   auto other_element_type = other2.get_element_type ();
    2624              : 
    2625         2362 :   return this_element_type->is_equal (*other_element_type);
    2626         2362 : }
    2627              : 
    2628              : bool
    2629            2 : ArrayType::is_zero_sized () const
    2630              : {
    2631            2 :   if (element_type.get_tyty ()->is_zero_sized ())
    2632              :     return true;
    2633              : 
    2634            1 :   auto *capacity_ty = get_capacity ();
    2635            1 :   if (capacity_ty != nullptr
    2636            1 :       && capacity_ty->get_kind () == TyTy::TypeKind::CONST)
    2637              :     {
    2638            1 :       auto *capacity_const = capacity_ty->as_const_type ();
    2639            1 :       auto &capacity_value
    2640            1 :         = *static_cast<TyTy::ConstValueType *> (capacity_const);
    2641            1 :       auto cap_tree = capacity_value.get_value ();
    2642            1 :       size_t cap_wi = (size_t) wi::to_wide (cap_tree).to_uhwi ();
    2643            1 :       if (cap_wi == 0)
    2644              :         {
    2645            1 :           return true;
    2646              :         }
    2647              :     }
    2648              :   return false;
    2649              : }
    2650              : 
    2651              : BaseType *
    2652        85504 : ArrayType::get_element_type () const
    2653              : {
    2654        85504 :   return element_type.get_tyty ();
    2655              : }
    2656              : 
    2657              : const TyVar &
    2658            1 : ArrayType::get_var_element_type () const
    2659              : {
    2660            1 :   return element_type;
    2661              : }
    2662              : 
    2663              : BaseType *
    2664        79868 : ArrayType::get_capacity () const
    2665              : {
    2666        79868 :   return capacity.get_tyty ();
    2667              : }
    2668              : 
    2669              : BaseType *
    2670          685 : ArrayType::clone () const
    2671              : {
    2672         1370 :   return new ArrayType (get_ref (), get_ty_ref (), ident.locus, capacity,
    2673          685 :                         element_type, get_combined_refs ());
    2674              : }
    2675              : 
    2676              : ArrayType *
    2677           57 : ArrayType::handle_substitions (SubstitutionArgumentMappings &mappings)
    2678              : {
    2679           57 :   auto &mappings_table = Analysis::Mappings::get ();
    2680              : 
    2681           57 :   ArrayType *ref = static_cast<ArrayType *> (clone ());
    2682           57 :   ref->set_ty_ref (mappings_table.get_next_hir_id ());
    2683              : 
    2684              :   // might be &T or &ADT so this needs to be recursive
    2685           57 :   auto base = ref->get_element_type ();
    2686           57 :   BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings);
    2687           57 :   ref->element_type = TyVar::subst_covariant_var (base, concrete);
    2688              : 
    2689              :   // handle capacity type
    2690           57 :   auto cap = ref->get_capacity ();
    2691           57 :   BaseType *concrete_cap
    2692           57 :     = Resolver::SubstMapperInternal::Resolve (cap, mappings);
    2693           57 :   rust_assert (concrete_cap->get_kind () == TyTy::TypeKind::CONST);
    2694           57 :   ref->capacity = TyVar::subst_covariant_var (cap, concrete_cap);
    2695              : 
    2696           57 :   return ref;
    2697              : }
    2698              : 
    2699              : bool
    2700          119 : ArrayType::contains_unsafe_cell () const
    2701              : {
    2702          119 :   return get_element_type ()->contains_unsafe_cell ();
    2703              : }
    2704              : 
    2705              : void
    2706         1923 : SliceType::accept_vis (TyVisitor &vis)
    2707              : {
    2708         1923 :   vis.visit (*this);
    2709         1923 : }
    2710              : 
    2711              : void
    2712          635 : SliceType::accept_vis (TyConstVisitor &vis) const
    2713              : {
    2714          635 :   vis.visit (*this);
    2715          635 : }
    2716              : 
    2717              : std::string
    2718        64093 : SliceType::as_string () const
    2719              : {
    2720       128186 :   return "[" + get_element_type ()->as_string () + "]";
    2721              : }
    2722              : 
    2723              : bool
    2724         4903 : SliceType::is_equal (const BaseType &other) const
    2725              : {
    2726         4903 :   if (get_kind () != other.get_kind ())
    2727              :     return false;
    2728              : 
    2729         3801 :   auto other2 = static_cast<const SliceType &> (other);
    2730              : 
    2731         3801 :   auto this_element_type = get_element_type ();
    2732         3801 :   auto other_element_type = other2.get_element_type ();
    2733              : 
    2734         3801 :   return this_element_type->is_equal (*other_element_type);
    2735         3801 : }
    2736              : 
    2737              : BaseType *
    2738       100046 : SliceType::get_element_type () const
    2739              : {
    2740       100046 :   return element_type.get_tyty ();
    2741              : }
    2742              : 
    2743              : const TyVar &
    2744           78 : SliceType::get_var_element_type () const
    2745              : {
    2746           78 :   return element_type;
    2747              : }
    2748              : 
    2749              : BaseType *
    2750        57636 : SliceType::clone () const
    2751              : {
    2752       115272 :   return new SliceType (get_ref (), get_ty_ref (), ident.locus,
    2753        57636 :                         element_type.clone (), get_combined_refs ());
    2754              : }
    2755              : 
    2756              : SliceType *
    2757         1618 : SliceType::handle_substitions (SubstitutionArgumentMappings &mappings)
    2758              : {
    2759         1618 :   auto &mappings_table = Analysis::Mappings::get ();
    2760              : 
    2761         1618 :   SliceType *ref = static_cast<SliceType *> (clone ());
    2762         1618 :   ref->set_ty_ref (mappings_table.get_next_hir_id ());
    2763              : 
    2764              :   // might be &T or &ADT so this needs to be recursive
    2765         1618 :   auto base = ref->get_element_type ();
    2766         1618 :   BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings);
    2767         1618 :   ref->element_type = TyVar::subst_covariant_var (base, concrete);
    2768              : 
    2769         1618 :   return ref;
    2770              : }
    2771              : 
    2772              : bool
    2773            0 : SliceType::contains_unsafe_cell () const
    2774              : {
    2775            0 :   return get_element_type ()->contains_unsafe_cell ();
    2776              : }
    2777              : 
    2778              : // BoolType
    2779              : 
    2780         4865 : BoolType::BoolType (HirId ref, std::set<HirId> refs)
    2781              :   : BaseType (ref, ref, KIND,
    2782         4865 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2783         9730 :               refs)
    2784         4865 : {}
    2785              : 
    2786        37057 : BoolType::BoolType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    2787              :   : BaseType (ref, ty_ref, KIND,
    2788        37057 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2789        74114 :               refs)
    2790        37057 : {}
    2791              : 
    2792              : std::string
    2793       337761 : BoolType::get_name () const
    2794              : {
    2795       337761 :   return as_string ();
    2796              : }
    2797              : 
    2798              : void
    2799          213 : BoolType::accept_vis (TyVisitor &vis)
    2800              : {
    2801          213 :   vis.visit (*this);
    2802          213 : }
    2803              : 
    2804              : void
    2805        10837 : BoolType::accept_vis (TyConstVisitor &vis) const
    2806              : {
    2807        10837 :   vis.visit (*this);
    2808        10837 : }
    2809              : 
    2810              : std::string
    2811       389758 : BoolType::as_string () const
    2812              : {
    2813       389758 :   return "bool";
    2814              : }
    2815              : 
    2816              : BaseType *
    2817        37057 : BoolType::clone () const
    2818              : {
    2819        37057 :   return new BoolType (get_ref (), get_ty_ref (), get_combined_refs ());
    2820              : }
    2821              : 
    2822              : // IntType
    2823              : 
    2824        24325 : IntType::IntType (HirId ref, IntKind kind, std::set<HirId> refs)
    2825              :   : BaseType (ref, ref, KIND,
    2826        24325 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2827              :               refs),
    2828        48650 :     int_kind (kind)
    2829        24325 : {}
    2830              : 
    2831       317683 : IntType::IntType (HirId ref, HirId ty_ref, IntKind kind, std::set<HirId> refs)
    2832              :   : BaseType (ref, ty_ref, KIND,
    2833       317683 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2834              :               refs),
    2835       635366 :     int_kind (kind)
    2836       317683 : {}
    2837              : 
    2838              : std::string
    2839      2591587 : IntType::get_name () const
    2840              : {
    2841      2591587 :   return as_string ();
    2842              : }
    2843              : 
    2844              : IntType::IntKind
    2845       800258 : IntType::get_int_kind () const
    2846              : {
    2847       800258 :   return int_kind;
    2848              : }
    2849              : 
    2850              : void
    2851         2096 : IntType::accept_vis (TyVisitor &vis)
    2852              : {
    2853         2096 :   vis.visit (*this);
    2854         2096 : }
    2855              : 
    2856              : void
    2857        86442 : IntType::accept_vis (TyConstVisitor &vis) const
    2858              : {
    2859        86442 :   vis.visit (*this);
    2860        86442 : }
    2861              : 
    2862              : std::string
    2863      2795581 : IntType::as_string () const
    2864              : {
    2865      2795581 :   switch (int_kind)
    2866              :     {
    2867       462649 :     case I8:
    2868       462649 :       return "i8";
    2869       392091 :     case I16:
    2870       392091 :       return "i16";
    2871      1506052 :     case I32:
    2872      1506052 :       return "i32";
    2873       391135 :     case I64:
    2874       391135 :       return "i64";
    2875        43654 :     case I128:
    2876        43654 :       return "i128";
    2877              :     }
    2878            0 :   rust_unreachable ();
    2879              :   return "__unknown_int_type";
    2880              : }
    2881              : 
    2882              : BaseType *
    2883       317683 : IntType::clone () const
    2884              : {
    2885       317683 :   return new IntType (get_ref (), get_ty_ref (), get_int_kind (),
    2886       317683 :                       get_combined_refs ());
    2887              : }
    2888              : 
    2889              : bool
    2890        87838 : IntType::is_equal (const BaseType &other) const
    2891              : {
    2892        87838 :   if (!BaseType::is_equal (other))
    2893              :     return false;
    2894              : 
    2895        66680 :   const IntType &o = static_cast<const IntType &> (other);
    2896        66680 :   return get_int_kind () == o.get_int_kind ();
    2897              : }
    2898              : 
    2899              : // UintType
    2900              : 
    2901        24325 : UintType::UintType (HirId ref, UintKind kind, std::set<HirId> refs)
    2902              :   : BaseType (ref, ref, KIND,
    2903        24325 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2904              :               refs),
    2905        48650 :     uint_kind (kind)
    2906        24325 : {}
    2907              : 
    2908       144633 : UintType::UintType (HirId ref, HirId ty_ref, UintKind kind,
    2909              :                     std::set<HirId> refs)
    2910              :   : BaseType (ref, ty_ref, KIND,
    2911       144633 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2912              :               refs),
    2913       289266 :     uint_kind (kind)
    2914       144633 : {}
    2915              : 
    2916              : std::string
    2917      4956286 : UintType::get_name () const
    2918              : {
    2919      4956286 :   return as_string ();
    2920              : }
    2921              : 
    2922              : UintType::UintKind
    2923       973194 : UintType::get_uint_kind () const
    2924              : {
    2925       973194 :   return uint_kind;
    2926              : }
    2927              : 
    2928              : void
    2929          676 : UintType::accept_vis (TyVisitor &vis)
    2930              : {
    2931          676 :   vis.visit (*this);
    2932          676 : }
    2933              : 
    2934              : void
    2935        67724 : UintType::accept_vis (TyConstVisitor &vis) const
    2936              : {
    2937        67724 :   vis.visit (*this);
    2938        67724 : }
    2939              : 
    2940              : std::string
    2941      5199155 : UintType::as_string () const
    2942              : {
    2943      5199155 :   switch (uint_kind)
    2944              :     {
    2945      1388196 :     case U8:
    2946      1388196 :       return "u8";
    2947      1193604 :     case U16:
    2948      1193604 :       return "u16";
    2949      1268965 :     case U32:
    2950      1268965 :       return "u32";
    2951      1300039 :     case U64:
    2952      1300039 :       return "u64";
    2953        48351 :     case U128:
    2954        48351 :       return "u128";
    2955              :     }
    2956            0 :   rust_unreachable ();
    2957              :   return "__unknown_uint_type";
    2958              : }
    2959              : 
    2960              : BaseType *
    2961       144633 : UintType::clone () const
    2962              : {
    2963       144633 :   return new UintType (get_ref (), get_ty_ref (), get_uint_kind (),
    2964       144633 :                        get_combined_refs ());
    2965              : }
    2966              : 
    2967              : bool
    2968        76547 : UintType::is_equal (const BaseType &other) const
    2969              : {
    2970        76547 :   if (!BaseType::is_equal (other))
    2971              :     return false;
    2972              : 
    2973        61256 :   const UintType &o = static_cast<const UintType &> (other);
    2974        61256 :   return get_uint_kind () == o.get_uint_kind ();
    2975              : }
    2976              : 
    2977              : // FloatType
    2978              : 
    2979         9730 : FloatType::FloatType (HirId ref, FloatKind kind, std::set<HirId> refs)
    2980              :   : BaseType (ref, ref, KIND,
    2981         9730 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2982              :               refs),
    2983        19460 :     float_kind (kind)
    2984         9730 : {}
    2985              : 
    2986        48688 : FloatType::FloatType (HirId ref, HirId ty_ref, FloatKind kind,
    2987              :                       std::set<HirId> refs)
    2988              :   : BaseType (ref, ty_ref, KIND,
    2989        48688 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2990              :               refs),
    2991        97376 :     float_kind (kind)
    2992        48688 : {}
    2993              : 
    2994              : std::string
    2995      1234885 : FloatType::get_name () const
    2996              : {
    2997      1234885 :   return as_string ();
    2998              : }
    2999              : 
    3000              : FloatType::FloatKind
    3001       112840 : FloatType::get_float_kind () const
    3002              : {
    3003       112840 :   return float_kind;
    3004              : }
    3005              : 
    3006              : void
    3007          188 : FloatType::accept_vis (TyVisitor &vis)
    3008              : {
    3009          188 :   vis.visit (*this);
    3010          188 : }
    3011              : 
    3012              : void
    3013        17565 : FloatType::accept_vis (TyConstVisitor &vis) const
    3014              : {
    3015        17565 :   vis.visit (*this);
    3016        17565 : }
    3017              : 
    3018              : std::string
    3019      1296442 : FloatType::as_string () const
    3020              : {
    3021      1296442 :   switch (float_kind)
    3022              :     {
    3023       653160 :     case F32:
    3024       653160 :       return "f32";
    3025       643282 :     case F64:
    3026       643282 :       return "f64";
    3027              :     }
    3028            0 :   rust_unreachable ();
    3029              :   return "__unknown_float_type";
    3030              : }
    3031              : 
    3032              : BaseType *
    3033        48688 : FloatType::clone () const
    3034              : {
    3035        48688 :   return new FloatType (get_ref (), get_ty_ref (), get_float_kind (),
    3036        48688 :                         get_combined_refs ());
    3037              : }
    3038              : 
    3039              : bool
    3040        12010 : FloatType::is_equal (const BaseType &other) const
    3041              : {
    3042        12010 :   if (!BaseType::is_equal (other))
    3043              :     return false;
    3044              : 
    3045        10138 :   const FloatType &o = static_cast<const FloatType &> (other);
    3046        10138 :   return get_float_kind () == o.get_float_kind ();
    3047              : }
    3048              : 
    3049              : // UsizeType
    3050              : 
    3051         4865 : USizeType::USizeType (HirId ref, std::set<HirId> refs)
    3052              :   : BaseType (ref, ref, KIND,
    3053         4865 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3054         9730 :               refs)
    3055         4865 : {}
    3056              : 
    3057        63131 : USizeType::USizeType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    3058              :   : BaseType (ref, ty_ref, KIND,
    3059        63131 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3060       126262 :               refs)
    3061        63131 : {}
    3062              : 
    3063              : std::string
    3064      3321998 : USizeType::get_name () const
    3065              : {
    3066      3321998 :   return as_string ();
    3067              : }
    3068              : 
    3069              : void
    3070          184 : USizeType::accept_vis (TyVisitor &vis)
    3071              : {
    3072          184 :   vis.visit (*this);
    3073          184 : }
    3074              : 
    3075              : void
    3076        37981 : USizeType::accept_vis (TyConstVisitor &vis) const
    3077              : {
    3078        37981 :   vis.visit (*this);
    3079        37981 : }
    3080              : 
    3081              : std::string
    3082      3367622 : USizeType::as_string () const
    3083              : {
    3084      3367622 :   return "usize";
    3085              : }
    3086              : 
    3087              : BaseType *
    3088        63131 : USizeType::clone () const
    3089              : {
    3090        63131 :   return new USizeType (get_ref (), get_ty_ref (), get_combined_refs ());
    3091              : }
    3092              : 
    3093              : // ISizeType
    3094              : 
    3095         5139 : ISizeType::ISizeType (HirId ref, std::set<HirId> refs)
    3096              :   : BaseType (ref, ref, KIND,
    3097         5139 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3098        10278 :               refs)
    3099         5139 : {}
    3100              : 
    3101        63360 : ISizeType::ISizeType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    3102              :   : BaseType (ref, ty_ref, KIND,
    3103        63360 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3104       126720 :               refs)
    3105        63360 : {}
    3106              : 
    3107              : std::string
    3108       685025 : ISizeType::get_name () const
    3109              : {
    3110       685025 :   return as_string ();
    3111              : }
    3112              : 
    3113              : void
    3114           74 : ISizeType::accept_vis (TyVisitor &vis)
    3115              : {
    3116           74 :   vis.visit (*this);
    3117           74 : }
    3118              : 
    3119              : void
    3120        23001 : ISizeType::accept_vis (TyConstVisitor &vis) const
    3121              : {
    3122        23001 :   vis.visit (*this);
    3123        23001 : }
    3124              : 
    3125              : std::string
    3126       704825 : ISizeType::as_string () const
    3127              : {
    3128       704825 :   return "isize";
    3129              : }
    3130              : 
    3131              : BaseType *
    3132        63360 : ISizeType::clone () const
    3133              : {
    3134        63360 :   return new ISizeType (get_ref (), get_ty_ref (), get_combined_refs ());
    3135              : }
    3136              : 
    3137              : // Char Type
    3138              : 
    3139         4865 : CharType::CharType (HirId ref, std::set<HirId> refs)
    3140              :   : BaseType (ref, ref, KIND,
    3141         4865 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3142         9730 :               refs)
    3143         4865 : {}
    3144              : 
    3145         9827 : CharType::CharType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    3146              :   : BaseType (ref, ty_ref, KIND,
    3147         9827 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3148        19654 :               refs)
    3149         9827 : {}
    3150              : 
    3151              : std::string
    3152       259836 : CharType::get_name () const
    3153              : {
    3154       259836 :   return as_string ();
    3155              : }
    3156              : 
    3157              : void
    3158           47 : CharType::accept_vis (TyVisitor &vis)
    3159              : {
    3160           47 :   vis.visit (*this);
    3161           47 : }
    3162              : 
    3163              : void
    3164         5922 : CharType::accept_vis (TyConstVisitor &vis) const
    3165              : {
    3166         5922 :   vis.visit (*this);
    3167         5922 : }
    3168              : 
    3169              : std::string
    3170       265257 : CharType::as_string () const
    3171              : {
    3172       265257 :   return "char";
    3173              : }
    3174              : 
    3175              : BaseType *
    3176         9827 : CharType::clone () const
    3177              : {
    3178         9827 :   return new CharType (get_ref (), get_ty_ref (), get_combined_refs ());
    3179              : }
    3180              : 
    3181              : // Reference Type
    3182              : 
    3183        47726 : ReferenceType::ReferenceType (HirId ref, TyVar base, Mutability mut,
    3184              :                               Region region, std::set<HirId> refs)
    3185              :   : BaseType (ref, ref, KIND,
    3186        47726 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3187              :               std::move (refs)),
    3188        95452 :     base (base), mut (mut), region (region)
    3189        47726 : {}
    3190              : 
    3191        80034 : ReferenceType::ReferenceType (HirId ref, HirId ty_ref, TyVar base,
    3192              :                               Mutability mut, Region region,
    3193              :                               std::set<HirId> refs)
    3194              :   : BaseType (ref, ty_ref, KIND,
    3195        80034 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3196              :               std::move (refs)),
    3197       160068 :     base (base), mut (mut), region (region)
    3198        80034 : {}
    3199              : 
    3200              : Mutability
    3201       218460 : ReferenceType::mutability () const
    3202              : {
    3203       218460 :   return mut;
    3204              : }
    3205              : 
    3206              : bool
    3207       929137 : ReferenceType::is_mutable () const
    3208              : {
    3209       929137 :   return mut == Mutability::Mut;
    3210              : }
    3211              : Region
    3212        80287 : ReferenceType::get_region () const
    3213              : {
    3214        80287 :   return region;
    3215              : }
    3216              : 
    3217              : bool
    3218         1964 : ReferenceType::is_dyn_object () const
    3219              : {
    3220         3928 :   return is_dyn_slice_type () || is_dyn_str_type () || is_dyn_obj_type ()
    3221         3911 :          || is_dyn_cstr_type ();
    3222              : }
    3223              : 
    3224              : static const TyTy::BaseType *
    3225        96994 : destructure_through_projections (const TyTy::BaseType *t)
    3226              : {
    3227        96994 :   const TyTy::BaseType *element = t->destructure ();
    3228       194295 :   for (int guard = 0; guard < 16; guard++)
    3229              :     {
    3230        97301 :       auto *proj = element->try_as<const TyTy::ProjectionType> ();
    3231          307 :       if (proj == nullptr)
    3232              :         break;
    3233          307 :       auto *normalized = Resolver::normalize_projection (
    3234              :         const_cast<TyTy::ProjectionType *> (proj), BUILTINS_LOCATION,
    3235              :         false /*emit_errors*/, false /*unify_self*/);
    3236          307 :       if (normalized == proj || normalized == nullptr
    3237          307 :           || normalized->get_kind () == TyTy::TypeKind::ERROR)
    3238              :         break;
    3239          307 :       element = normalized->destructure ();
    3240              :     }
    3241        96994 :   return element;
    3242              : }
    3243              : 
    3244              : bool
    3245        20591 : ReferenceType::is_dyn_slice_type (const TyTy::SliceType **slice) const
    3246              : {
    3247        20591 :   const TyTy::BaseType *element = destructure_through_projections (get_base ());
    3248        20591 :   if (element->get_kind () != TyTy::TypeKind::SLICE)
    3249              :     return false;
    3250          651 :   if (slice == nullptr)
    3251              :     return true;
    3252              : 
    3253          651 :   *slice = static_cast<const TyTy::SliceType *> (element);
    3254          651 :   return true;
    3255              : }
    3256              : 
    3257              : bool
    3258        19983 : ReferenceType::is_dyn_str_type (const TyTy::StrType **str) const
    3259              : {
    3260        19983 :   const TyTy::BaseType *element = destructure_through_projections (get_base ());
    3261        19983 :   if (element->get_kind () != TyTy::TypeKind::STR)
    3262              :     return false;
    3263         4137 :   if (str == nullptr)
    3264              :     return true;
    3265              : 
    3266         4128 :   *str = static_cast<const TyTy::StrType *> (element);
    3267         4128 :   return true;
    3268              : }
    3269              : 
    3270              : bool
    3271        15812 : ReferenceType::is_dyn_obj_type (const TyTy::DynamicObjectType **dyn) const
    3272              : {
    3273        15812 :   const TyTy::BaseType *element = destructure_through_projections (get_base ());
    3274        15812 :   if (element->get_kind () != TyTy::TypeKind::DYNAMIC)
    3275              :     return false;
    3276          702 :   if (dyn == nullptr)
    3277              :     return true;
    3278              : 
    3279          685 :   *dyn = static_cast<const TyTy::DynamicObjectType *> (element);
    3280          685 :   return true;
    3281              : }
    3282              : 
    3283              : bool
    3284        15110 : ReferenceType::is_dyn_cstr_type (const TyTy::ADTType **adt) const
    3285              : {
    3286        15110 :   if (get_base ()->get_kind () != TyTy::TypeKind::ADT)
    3287              :     return false;
    3288              : 
    3289         3817 :   const TyTy::ADTType *adt_ty
    3290         3817 :     = static_cast<const TyTy::ADTType *> (get_base ());
    3291         3817 :   auto &mappings = Analysis::Mappings::get ();
    3292         3817 :   auto cstr_item = mappings.lookup_lang_item (LangItem::Kind::CSTR);
    3293              : 
    3294         3817 :   if (!cstr_item.has_value ())
    3295              :     return false;
    3296              : 
    3297           56 :   if (cstr_item.value () != adt_ty->get_id ())
    3298            0 :     return false;
    3299              : 
    3300           56 :   *adt = adt_ty;
    3301           56 :   return true;
    3302              : }
    3303              : 
    3304              : void
    3305        10763 : ReferenceType::accept_vis (TyVisitor &vis)
    3306              : {
    3307        10763 :   vis.visit (*this);
    3308        10763 : }
    3309              : 
    3310              : void
    3311        19969 : ReferenceType::accept_vis (TyConstVisitor &vis) const
    3312              : {
    3313        19969 :   vis.visit (*this);
    3314        19969 : }
    3315              : 
    3316              : std::string
    3317        75833 : ReferenceType::as_string () const
    3318              : {
    3319       297922 :   return std::string ("&") + (is_mutable () ? "mut" : "") + " "
    3320       151666 :          + get_base ()->as_string ();
    3321              : }
    3322              : 
    3323              : std::string
    3324       809752 : ReferenceType::get_name () const
    3325              : {
    3326      3198427 :   return std::string ("&") + (is_mutable () ? "mut" : "") + " "
    3327      1619504 :          + get_base ()->get_name ();
    3328              : }
    3329              : 
    3330              : bool
    3331        36856 : ReferenceType::is_equal (const BaseType &other) const
    3332              : {
    3333        36856 :   if (get_kind () != other.get_kind ())
    3334              :     return false;
    3335              : 
    3336        36215 :   auto other2 = static_cast<const ReferenceType &> (other);
    3337        36215 :   if (mutability () != other2.mutability ())
    3338              :     return false;
    3339              : 
    3340        32958 :   return get_base ()->is_equal (*other2.get_base ());
    3341        36215 : }
    3342              : 
    3343              : BaseType *
    3344      1402131 : ReferenceType::get_base () const
    3345              : {
    3346      1402131 :   return base.get_tyty ();
    3347              : }
    3348              : 
    3349              : const TyVar &
    3350         1433 : ReferenceType::get_var_element_type () const
    3351              : {
    3352         1433 :   return base;
    3353              : }
    3354              : 
    3355              : BaseType *
    3356        79809 : ReferenceType::clone () const
    3357              : {
    3358        79809 :   return new ReferenceType (get_ref (), get_ty_ref (), base, mutability (),
    3359        79809 :                             get_region (), get_combined_refs ());
    3360              : }
    3361              : 
    3362              : ReferenceType *
    3363        10510 : ReferenceType::handle_substitions (SubstitutionArgumentMappings &mappings)
    3364              : {
    3365        10510 :   auto &mappings_table = Analysis::Mappings::get ();
    3366              : 
    3367        10510 :   ReferenceType *ref = static_cast<ReferenceType *> (clone ());
    3368        10510 :   ref->set_ty_ref (mappings_table.get_next_hir_id ());
    3369              : 
    3370              :   // might be &T or &ADT so this needs to be recursive
    3371        10510 :   auto base = ref->get_base ();
    3372        10510 :   BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings);
    3373        10510 :   ref->base = TyVar::subst_covariant_var (base, concrete);
    3374              : 
    3375        10510 :   return ref;
    3376              : }
    3377              : 
    3378              : // PointerType
    3379              : 
    3380        14434 : PointerType::PointerType (HirId ref, TyVar base, Mutability mut,
    3381              :                           std::set<HirId> refs)
    3382              :   : BaseType (ref, ref, KIND,
    3383        14434 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3384              :               refs),
    3385        28868 :     base (base), mut (mut)
    3386        14434 : {}
    3387              : 
    3388        17182 : PointerType::PointerType (HirId ref, HirId ty_ref, TyVar base, Mutability mut,
    3389              :                           std::set<HirId> refs)
    3390              :   : BaseType (ref, ty_ref, KIND,
    3391        17182 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3392              :               refs),
    3393        34364 :     base (base), mut (mut)
    3394        17182 : {}
    3395              : 
    3396              : Mutability
    3397        66778 : PointerType::mutability () const
    3398              : {
    3399        66778 :   return mut;
    3400              : }
    3401              : 
    3402              : bool
    3403       213137 : PointerType::is_mutable () const
    3404              : {
    3405       213137 :   return mut == Mutability::Mut;
    3406              : }
    3407              : 
    3408              : bool
    3409          299 : PointerType::is_const () const
    3410              : {
    3411          299 :   return mut == Mutability::Imm;
    3412              : }
    3413              : 
    3414              : bool
    3415         4185 : PointerType::is_dyn_object () const
    3416              : {
    3417         4185 :   return is_dyn_slice_type () || is_dyn_str_type () || is_dyn_obj_type ();
    3418              : }
    3419              : 
    3420              : bool
    3421        14791 : PointerType::is_dyn_slice_type (const TyTy::SliceType **slice) const
    3422              : {
    3423        14791 :   const TyTy::BaseType *element = destructure_through_projections (get_base ());
    3424        14791 :   if (element->get_kind () != TyTy::TypeKind::SLICE)
    3425              :     return false;
    3426          564 :   if (slice == nullptr)
    3427              :     return true;
    3428              : 
    3429          564 :   *slice = static_cast<const TyTy::SliceType *> (element);
    3430          564 :   return true;
    3431              : }
    3432              : 
    3433              : bool
    3434        14227 : PointerType::is_dyn_str_type (const TyTy::StrType **str) const
    3435              : {
    3436        14227 :   const TyTy::BaseType *element = destructure_through_projections (get_base ());
    3437        14227 :   if (element->get_kind () != TyTy::TypeKind::STR)
    3438              :     return false;
    3439         2637 :   if (str == nullptr)
    3440              :     return true;
    3441              : 
    3442         2637 :   *str = static_cast<const TyTy::StrType *> (element);
    3443         2637 :   return true;
    3444              : }
    3445              : 
    3446              : bool
    3447        11590 : PointerType::is_dyn_obj_type (const TyTy::DynamicObjectType **dyn) const
    3448              : {
    3449        11590 :   const TyTy::BaseType *element = destructure_through_projections (get_base ());
    3450        11590 :   if (element->get_kind () != TyTy::TypeKind::DYNAMIC)
    3451              :     return false;
    3452           12 :   if (dyn == nullptr)
    3453              :     return true;
    3454              : 
    3455           12 :   *dyn = static_cast<const TyTy::DynamicObjectType *> (element);
    3456           12 :   return true;
    3457              : }
    3458              : 
    3459              : void
    3460         3248 : PointerType::accept_vis (TyVisitor &vis)
    3461              : {
    3462         3248 :   vis.visit (*this);
    3463         3248 : }
    3464              : 
    3465              : void
    3466        11794 : PointerType::accept_vis (TyConstVisitor &vis) const
    3467              : {
    3468        11794 :   vis.visit (*this);
    3469        11794 : }
    3470              : 
    3471              : std::string
    3472        14164 : PointerType::as_string () const
    3473              : {
    3474        53256 :   return std::string ("* ") + (is_mutable () ? "mut" : "const") + " "
    3475        28328 :          + get_base ()->as_string ();
    3476              : }
    3477              : 
    3478              : std::string
    3479       170699 : PointerType::get_name () const
    3480              : {
    3481       655122 :   return std::string ("* ") + (is_mutable () ? "mut" : "const") + " "
    3482       341398 :          + get_base ()->get_name ();
    3483              : }
    3484              : 
    3485              : bool
    3486        16770 : PointerType::is_equal (const BaseType &other) const
    3487              : {
    3488        16770 :   if (get_kind () != other.get_kind ())
    3489              :     return false;
    3490              : 
    3491        16434 :   auto other2 = static_cast<const PointerType &> (other);
    3492        16434 :   if (mutability () != other2.mutability ())
    3493              :     return false;
    3494              : 
    3495        16350 :   return get_base ()->is_equal (*other2.get_base ());
    3496        16434 : }
    3497              : 
    3498              : BaseType *
    3499       337208 : PointerType::get_base () const
    3500              : {
    3501       337208 :   return base.get_tyty ();
    3502              : }
    3503              : 
    3504              : const TyVar &
    3505          496 : PointerType::get_var_element_type () const
    3506              : {
    3507          496 :   return base;
    3508              : }
    3509              : 
    3510              : BaseType *
    3511        16686 : PointerType::clone () const
    3512              : {
    3513        16686 :   return new PointerType (get_ref (), get_ty_ref (), base, mutability (),
    3514        16686 :                           get_combined_refs ());
    3515              : }
    3516              : 
    3517              : PointerType *
    3518         3028 : PointerType::handle_substitions (SubstitutionArgumentMappings &mappings)
    3519              : {
    3520         3028 :   auto &mappings_table = Analysis::Mappings::get ();
    3521              : 
    3522         3028 :   PointerType *ref = static_cast<PointerType *> (clone ());
    3523         3028 :   ref->set_ty_ref (mappings_table.get_next_hir_id ());
    3524              : 
    3525              :   // might be &T or &ADT so this needs to be recursive
    3526         3028 :   auto base = ref->get_base ();
    3527         3028 :   BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings);
    3528         3028 :   ref->base = TyVar::subst_covariant_var (base, concrete);
    3529              : 
    3530         3028 :   return ref;
    3531              : }
    3532              : 
    3533              : // PARAM Type
    3534              : 
    3535        14971 : ParamType::ParamType (std::string symbol, location_t locus, HirId ref,
    3536              :                       std::vector<TypeBoundPredicate> specified_bounds,
    3537              :                       std::set<HirId> refs)
    3538              :   : BaseGeneric (ref, ref, KIND,
    3539        29942 :                  {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, symbol),
    3540              :                   locus},
    3541              :                  specified_bounds, refs),
    3542        44913 :     is_trait_self (false), symbol (symbol)
    3543        14971 : {}
    3544              : 
    3545     95110976 : ParamType::ParamType (bool is_trait_self, std::string symbol, location_t locus,
    3546              :                       HirId ref, HirId ty_ref,
    3547              :                       std::vector<TypeBoundPredicate> specified_bounds,
    3548              :                       std::set<HirId> refs)
    3549              :   : BaseGeneric (ref, ty_ref, KIND,
    3550    190221952 :                  {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, symbol),
    3551              :                   locus},
    3552              :                  specified_bounds, refs),
    3553    285332928 :     is_trait_self (is_trait_self), symbol (symbol)
    3554     95110976 : {}
    3555              : 
    3556              : bool
    3557      4980857 : ParamType::can_resolve () const
    3558              : {
    3559      4980857 :   return get_ref () != get_ty_ref ();
    3560              : }
    3561              : 
    3562              : void
    3563        80662 : ParamType::accept_vis (TyVisitor &vis)
    3564              : {
    3565        80662 :   vis.visit (*this);
    3566        80662 : }
    3567              : 
    3568              : void
    3569          334 : ParamType::accept_vis (TyConstVisitor &vis) const
    3570              : {
    3571          334 :   vis.visit (*this);
    3572          334 : }
    3573              : 
    3574              : std::string
    3575       227944 : ParamType::as_string () const
    3576              : {
    3577       227944 :   if (!can_resolve ())
    3578              :     {
    3579       178952 :       return get_symbol () + " REF: " + std::to_string (get_ref ());
    3580              :     }
    3581              : 
    3582       138468 :   BaseType *lookup = resolve ();
    3583       276936 :   return get_symbol () + "=" + lookup->as_string ();
    3584              : }
    3585              : 
    3586              : std::string
    3587      2480910 : ParamType::get_name () const
    3588              : {
    3589      2480910 :   if (!can_resolve ())
    3590       943384 :     return get_symbol ();
    3591              : 
    3592      1539291 :   static std::vector<const ParamType *> active;
    3593      3075052 :   if (Resolver::ScopedPush<const ParamType *>::contains (active, this))
    3594            0 :     return get_symbol ();
    3595              : 
    3596      1537526 :   Resolver::ScopedPush<const ParamType *> guard (active, this);
    3597              : 
    3598      1537526 :   return destructure ()->get_name ();
    3599      1537526 : }
    3600              : 
    3601              : BaseType *
    3602     95110976 : ParamType::clone () const
    3603              : {
    3604     95110976 :   return new ParamType (is_trait_self, get_symbol (), ident.locus, get_ref (),
    3605              :                         get_ty_ref (), get_specified_bounds (),
    3606    190221952 :                         get_combined_refs ());
    3607              : }
    3608              : 
    3609              : std::string
    3610     96825565 : ParamType::get_symbol () const
    3611              : {
    3612     96825565 :   return symbol;
    3613              : }
    3614              : 
    3615              : BaseType *
    3616      3437743 : ParamType::resolve () const
    3617              : {
    3618      3437743 :   TyVar var (get_ty_ref ());
    3619      3437743 :   BaseType *r = var.get_tyty ();
    3620              : 
    3621      7002311 :   while (r->get_kind () == TypeKind::PARAM)
    3622              :     {
    3623      2117913 :       ParamType *rr = static_cast<ParamType *> (r);
    3624      2117913 :       if (!rr->can_resolve ())
    3625              :         break;
    3626              : 
    3627       126825 :       TyVar v (rr->get_ty_ref ());
    3628       126825 :       BaseType *n = v.get_tyty ();
    3629              : 
    3630              :       // fix infinite loop
    3631       126825 :       if (r == n)
    3632              :         break;
    3633              : 
    3634       126825 :       r = n;
    3635              :     }
    3636              : 
    3637      3437743 :   if (r->get_kind () == TypeKind::PARAM && (r->get_ref () == r->get_ty_ref ()))
    3638      1991088 :     return TyVar (r->get_ty_ref ()).get_tyty ();
    3639              : 
    3640              :   return r;
    3641              : }
    3642              : 
    3643              : bool
    3644        50911 : ParamType::is_equal (const BaseType &other) const
    3645              : {
    3646        50911 :   if (get_kind () != other.get_kind ())
    3647              :     {
    3648        14638 :       if (!can_resolve ())
    3649              :         return false;
    3650              : 
    3651         9972 :       return resolve ()->is_equal (other);
    3652              :     }
    3653              : 
    3654        36273 :   auto other2 = static_cast<const ParamType &> (other);
    3655        36273 :   if (can_resolve () != other2.can_resolve ())
    3656              :     return false;
    3657              : 
    3658        34676 :   if (can_resolve ())
    3659        23420 :     return Resolver::types_compatable (TyTy::TyWithLocation (resolve ()),
    3660        23420 :                                        TyTy::TyWithLocation (other2.resolve ()),
    3661              :                                        UNKNOWN_LOCATION, false, false);
    3662              : 
    3663        11256 :   return get_symbol ().compare (other2.get_symbol ()) == 0;
    3664        36273 : }
    3665              : 
    3666              : ParamType *
    3667        79200 : ParamType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
    3668              : {
    3669        79200 :   SubstitutionArg arg = SubstitutionArg::error ();
    3670        79200 :   bool ok = subst_mappings.get_argument_for_symbol (this, &arg);
    3671        79200 :   if (!ok || arg.is_error ())
    3672              :     return this;
    3673              : 
    3674        58496 :   ParamType *p = static_cast<ParamType *> (clone ());
    3675        58496 :   subst_mappings.on_param_subst (*p, arg);
    3676              : 
    3677        58496 :   const BaseType *resolved = arg.get_tyty ();
    3678        58496 :   if (resolved->get_kind () == TyTy::TypeKind::PARAM)
    3679              :     {
    3680         8045 :       const ParamType &pp = *static_cast<const ParamType *> (resolved);
    3681         8045 :       if (pp.can_resolve ())
    3682         7554 :         pp.resolve ();
    3683              :     }
    3684              : 
    3685              :   // this is the new subst that this needs to pass
    3686        58496 :   p->set_ref (mappings.get_next_hir_id ());
    3687        58496 :   p->set_ty_ref (arg.get_tyty ()->get_ref ());
    3688              : 
    3689        58496 :   return p;
    3690              : }
    3691              : 
    3692              : void
    3693         3958 : ParamType::set_implicit_self_trait ()
    3694              : {
    3695         3958 :   is_trait_self = true;
    3696         3958 : }
    3697              : 
    3698              : bool
    3699        41157 : ParamType::is_implicit_self_trait () const
    3700              : {
    3701        41157 :   return is_trait_self;
    3702              : }
    3703              : 
    3704              : static std::string
    3705        62759 : generate_tree_str (tree value)
    3706              : {
    3707        62759 :   pretty_printer pp;
    3708        62759 :   dump_generic_node (&pp, value, 0, TDF_NONE, true);
    3709        62759 :   std::string result = pp_formatted_text (&pp);
    3710              : 
    3711       125518 :   if (!result.empty () && result.back () == '\n')
    3712            0 :     result.pop_back ();
    3713              : 
    3714       125518 :   return result;
    3715        62759 : }
    3716              : 
    3717              : // ---
    3718              : 
    3719          809 : ConstParamType::ConstParamType (std::string symbol, location_t locus,
    3720              :                                 BaseType *type, HirId ref, HirId ty_ref,
    3721              :                                 std::set<HirId> refs)
    3722              :   : BaseConstType (type),
    3723              :     BaseGeneric (ref, ty_ref, KIND,
    3724         1618 :                  {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, symbol),
    3725              :                   locus},
    3726              :                  {}, refs),
    3727         2427 :     symbol (symbol)
    3728          809 : {}
    3729              : 
    3730              : BaseConstType::ConstKind
    3731         5048 : ConstParamType::const_kind () const
    3732              : {
    3733         5048 :   return BaseConstType::ConstKind::Decl;
    3734              : }
    3735              : 
    3736              : std::string
    3737         2816 : ConstParamType::get_symbol () const
    3738              : {
    3739         2816 :   return symbol;
    3740              : }
    3741              : 
    3742              : bool
    3743         4502 : ConstParamType::can_resolve () const
    3744              : {
    3745         4502 :   return get_ref () != get_ty_ref ();
    3746              : }
    3747              : 
    3748              : BaseType *
    3749         5304 : ConstParamType::resolve () const
    3750              : {
    3751         5304 :   TyVar var (get_ty_ref ());
    3752         5304 :   BaseType *r = var.get_tyty ();
    3753              : 
    3754        10748 :   while (r->get_kind () == TypeKind::CONST)
    3755              :     {
    3756         5444 :       TyVar v (r->get_ty_ref ());
    3757         5444 :       BaseType *n = v.get_tyty ();
    3758              : 
    3759              :       // fix infinite loop
    3760         5444 :       if (r == n)
    3761              :         break;
    3762              : 
    3763          140 :       r = n;
    3764              :     }
    3765              : 
    3766         5304 :   if (r->get_kind () == TypeKind::CONST && (r->get_ref () == r->get_ty_ref ()))
    3767              :     {
    3768         5304 :       auto *const_type = r->as_const_type ();
    3769         5304 :       if (const_type->const_kind () != BaseConstType::ConstKind::Value)
    3770         1462 :         return TyVar (r->get_ty_ref ()).get_tyty ();
    3771              :     }
    3772              : 
    3773              :   return r;
    3774              : }
    3775              : 
    3776              : void
    3777           57 : ConstParamType::accept_vis (TyVisitor &vis)
    3778              : {
    3779           57 :   vis.visit (*this);
    3780           57 : }
    3781              : 
    3782              : void
    3783            0 : ConstParamType::accept_vis (TyConstVisitor &vis) const
    3784              : {
    3785            0 :   vis.visit (*this);
    3786            0 : }
    3787              : 
    3788              : std::string
    3789          165 : ConstParamType::as_string () const
    3790              : {
    3791          165 :   if (!can_resolve ())
    3792              :     {
    3793          330 :       return get_symbol () + " CONST_REF: " + std::to_string (get_ref ());
    3794              :     }
    3795              : 
    3796            0 :   BaseType *lookup = resolve ();
    3797              :   // Avoid infinite recursion if resolve() returns this same type
    3798            0 :   if (lookup == this->as_base_type ())
    3799              :     {
    3800            0 :       return get_symbol () + " CONST_REF: " + std::to_string (get_ref ());
    3801              :     }
    3802              : 
    3803            0 :   return get_symbol () + "=" + lookup->as_string ();
    3804              : }
    3805              : 
    3806              : BaseType *
    3807          678 : ConstParamType::clone () const
    3808              : {
    3809         1356 :   return new ConstParamType (get_symbol (), ident.locus, specified_type,
    3810         1356 :                              get_ref (), get_ty_ref (), get_combined_refs ());
    3811              : }
    3812              : 
    3813              : std::string
    3814         3297 : ConstParamType::get_name () const
    3815              : {
    3816         3297 :   if (!can_resolve ())
    3817          662 :     return get_symbol ();
    3818              : 
    3819         2635 :   BaseType *lookup = resolve ();
    3820         2635 :   if (lookup == this->as_base_type ())
    3821            0 :     return get_symbol () + ":" + get_specified_type ()->get_name ();
    3822              : 
    3823         2635 :   return lookup->get_name ();
    3824              : }
    3825              : 
    3826              : bool
    3827          331 : ConstParamType::is_equal (const BaseType &other) const
    3828              : {
    3829          331 :   if (get_kind () != other.get_kind ())
    3830              :     {
    3831            1 :       if (!can_resolve ())
    3832              :         return false;
    3833              : 
    3834            0 :       return resolve ()->is_equal (other);
    3835              :     }
    3836              : 
    3837          330 :   auto other_const = other.as_const_type ();
    3838          330 :   if (other_const->const_kind () != BaseConstType::ConstKind::Decl)
    3839              :     return false;
    3840              : 
    3841          323 :   auto &other2 = static_cast<const ConstParamType &> (*other_const);
    3842          323 :   if (can_resolve () != other2.can_resolve ())
    3843              :     return false;
    3844              : 
    3845          274 :   if (can_resolve ())
    3846              :     {
    3847              :       // Compare the resolved ty_ref values to avoid infinite recursion
    3848              :       // through types_compatable/unification
    3849          232 :       BaseType *lhs = resolve ();
    3850          232 :       BaseType *rhs = other2.resolve ();
    3851              : 
    3852              :       // If they resolve to the same type (same ty_ref), they're equal
    3853          232 :       if (lhs->get_ty_ref () == rhs->get_ty_ref ())
    3854              :         return true;
    3855              : 
    3856              :       // Otherwise check if the resolved types are equal
    3857              :       // Avoid recursion by checking if we'd be comparing ConstParamTypes again
    3858          199 :       if (lhs->get_kind () == TypeKind::CONST
    3859          199 :           && lhs->as_const_type ()->const_kind ()
    3860              :                == BaseConstType::ConstKind::Decl)
    3861              :         return false; // Would cause recursion, so not equal
    3862              : 
    3863          199 :       return lhs->is_equal (*rhs);
    3864              :     }
    3865              : 
    3866           42 :   return get_symbol ().compare (other2.get_symbol ()) == 0;
    3867              : }
    3868              : 
    3869              : BaseType *
    3870           57 : ConstParamType::handle_substitions (
    3871              :   SubstitutionArgumentMappings &subst_mappings)
    3872              : {
    3873           57 :   SubstitutionArg arg = SubstitutionArg::error ();
    3874           57 :   bool ok = subst_mappings.get_argument_for_symbol (this, &arg);
    3875           57 :   if (!ok || arg.is_error ())
    3876            0 :     return this;
    3877              : 
    3878           57 :   ConstParamType *p = static_cast<ConstParamType *> (clone ());
    3879           57 :   const BaseType *resolved = arg.get_tyty ();
    3880              : 
    3881              :   // this is the new subst that this needs to pass
    3882           57 :   p->set_ref (mappings.get_next_hir_id ());
    3883           57 :   p->set_ty_ref (resolved->get_ref ());
    3884              : 
    3885           57 :   return p;
    3886              : }
    3887              : 
    3888              : // --- ConstValueType
    3889              : 
    3890         2979 : ConstValueType::ConstValueType (tree value, BaseType *type, HirId ref,
    3891              :                                 HirId ty_ref, std::set<HirId> refs)
    3892              :   : BaseType (ref, ty_ref, KIND,
    3893         2979 :               {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
    3894              :               refs),
    3895         5958 :     BaseConstType (type), folded_val (value)
    3896         2979 : {}
    3897              : 
    3898              : BaseConstType::ConstKind
    3899        74289 : ConstValueType::const_kind () const
    3900              : {
    3901        74289 :   return BaseConstType::ConstKind::Value;
    3902              : }
    3903              : 
    3904              : void
    3905            0 : ConstValueType::accept_vis (TyVisitor &vis)
    3906              : {
    3907            0 :   vis.visit (*this);
    3908            0 : }
    3909              : 
    3910              : void
    3911            0 : ConstValueType::accept_vis (TyConstVisitor &vis) const
    3912              : {
    3913            0 :   vis.visit (*this);
    3914            0 : }
    3915              : 
    3916              : std::string
    3917        62759 : ConstValueType::as_string () const
    3918              : {
    3919        62759 :   return generate_tree_str (folded_val);
    3920              : }
    3921              : 
    3922              : BaseType *
    3923          170 : ConstValueType::clone () const
    3924              : {
    3925          340 :   return new ConstValueType (folded_val, specified_type, get_ref (),
    3926          170 :                              get_ty_ref (), get_combined_refs ());
    3927              : }
    3928              : 
    3929              : std::string
    3930         5971 : ConstValueType::get_name () const
    3931              : {
    3932         5971 :   return as_string ();
    3933              : }
    3934              : 
    3935              : bool
    3936         1900 : ConstValueType::is_equal (const BaseType &other) const
    3937              : {
    3938         1900 :   if (get_kind () != other.get_kind ())
    3939              :     return false;
    3940              : 
    3941         1900 :   auto other_const = other.as_const_type ();
    3942         1900 :   if (other_const->const_kind () != BaseConstType::ConstKind::Value)
    3943              :     return false;
    3944              : 
    3945         1817 :   auto &other2 = static_cast<const ConstValueType &> (*other_const);
    3946         1817 :   return folded_val == other2.folded_val;
    3947              : }
    3948              : 
    3949              : tree
    3950         7711 : ConstValueType::get_value () const
    3951              : {
    3952         7711 :   return folded_val;
    3953              : }
    3954              : 
    3955              : // --- ConstInferType
    3956              : 
    3957          108 : ConstInferType::ConstInferType (BaseType *type, HirId ref, HirId ty_ref,
    3958              :                                 std::set<HirId> refs)
    3959              :   : BaseType (ref, ty_ref, KIND,
    3960          108 :               {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
    3961              :               refs),
    3962          216 :     BaseConstType (type)
    3963          108 : {}
    3964              : 
    3965              : BaseConstType::ConstKind
    3966         1028 : ConstInferType::const_kind () const
    3967              : {
    3968         1028 :   return BaseConstType::ConstKind::Infer;
    3969              : }
    3970              : 
    3971              : void
    3972            0 : ConstInferType::accept_vis (TyVisitor &vis)
    3973              : {
    3974            0 :   vis.visit (*this);
    3975            0 : }
    3976              : 
    3977              : void
    3978            0 : ConstInferType::accept_vis (TyConstVisitor &vis) const
    3979              : {
    3980            0 :   vis.visit (*this);
    3981            0 : }
    3982              : 
    3983              : std::string
    3984          324 : ConstInferType::as_string () const
    3985              : {
    3986          648 :   return specified_type->get_name () + "-?";
    3987              : }
    3988              : 
    3989              : BaseType *
    3990            0 : ConstInferType::clone () const
    3991              : {
    3992            0 :   auto &mappings = Analysis::Mappings::get ();
    3993            0 :   auto context = Resolver::TypeCheckContext::get ();
    3994              : 
    3995            0 :   ConstInferType *clone
    3996            0 :     = new ConstInferType (specified_type, mappings.get_next_hir_id (),
    3997            0 :                           get_ty_ref (), get_combined_refs ());
    3998              : 
    3999            0 :   context->insert_type (Analysis::NodeMapping (mappings.get_current_crate (),
    4000              :                                                UNKNOWN_NODEID,
    4001              :                                                clone->get_ref (),
    4002            0 :                                                UNKNOWN_LOCAL_DEFID),
    4003              :                         clone);
    4004            0 :   mappings.insert_location (clone->get_ref (),
    4005              :                             mappings.lookup_location (get_ref ()));
    4006              : 
    4007            0 :   clone->append_reference (get_ref ());
    4008              : 
    4009            0 :   return clone;
    4010              : }
    4011              : 
    4012              : std::string
    4013          159 : ConstInferType::get_name () const
    4014              : {
    4015          159 :   return as_string ();
    4016              : }
    4017              : 
    4018              : bool
    4019           46 : ConstInferType::is_equal (const BaseType &other) const
    4020              : {
    4021           46 :   if (get_kind () != other.get_kind ())
    4022              :     return false;
    4023              : 
    4024           46 :   auto other_const = other.as_const_type ();
    4025           46 :   if (other_const->const_kind () != BaseConstType::ConstKind::Infer)
    4026              :     return false;
    4027              : 
    4028            0 :   return get_ref () == other.get_ref ();
    4029              : }
    4030              : 
    4031              : // --- ConstErrorType
    4032              : 
    4033            1 : ConstErrorType::ConstErrorType (BaseType *type, HirId ref, HirId ty_ref,
    4034              :                                 std::set<HirId> refs)
    4035              :   : BaseType (ref, ty_ref, KIND,
    4036            1 :               {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
    4037              :               refs),
    4038            2 :     BaseConstType (type)
    4039            1 : {}
    4040              : 
    4041              : BaseConstType::ConstKind
    4042            0 : ConstErrorType::const_kind () const
    4043              : {
    4044            0 :   return BaseConstType::ConstKind::Error;
    4045              : }
    4046              : 
    4047              : void
    4048            0 : ConstErrorType::accept_vis (TyVisitor &vis)
    4049              : {
    4050            0 :   vis.visit (*this);
    4051            0 : }
    4052              : 
    4053              : void
    4054            0 : ConstErrorType::accept_vis (TyConstVisitor &vis) const
    4055              : {
    4056            0 :   vis.visit (*this);
    4057            0 : }
    4058              : 
    4059              : std::string
    4060            0 : ConstErrorType::as_string () const
    4061              : {
    4062            0 :   return "<const_error>";
    4063              : }
    4064              : 
    4065              : BaseType *
    4066            0 : ConstErrorType::clone () const
    4067              : {
    4068            0 :   return new ConstErrorType (specified_type, get_ref (), get_ty_ref (),
    4069            0 :                              get_combined_refs ());
    4070              : }
    4071              : 
    4072              : std::string
    4073            0 : ConstErrorType::get_name () const
    4074              : {
    4075            0 :   return as_string ();
    4076              : }
    4077              : 
    4078              : bool
    4079            0 : ConstErrorType::is_equal (const BaseType &other) const
    4080              : {
    4081            0 :   if (get_kind () != other.get_kind ())
    4082              :     return false;
    4083              : 
    4084            0 :   auto other_const = other.as_const_type ();
    4085            0 :   return other_const->const_kind () == BaseConstType::ConstKind::Error;
    4086              : }
    4087              : 
    4088              : // OpaqueType
    4089              : 
    4090           29 : OpaqueType::OpaqueType (location_t locus, HirId ref,
    4091              :                         std::vector<TypeBoundPredicate> specified_bounds,
    4092              :                         std::set<HirId> refs)
    4093              :   : BaseType (ref, ref, KIND,
    4094           58 :               {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, "impl"),
    4095              :                locus},
    4096           87 :               specified_bounds, refs)
    4097           29 : {}
    4098              : 
    4099           57 : OpaqueType::OpaqueType (location_t locus, HirId ref, HirId ty_ref,
    4100              :                         std::vector<TypeBoundPredicate> specified_bounds,
    4101              :                         std::set<HirId> refs)
    4102              :   : BaseType (ref, ty_ref, KIND,
    4103          114 :               {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, "impl"),
    4104              :                locus},
    4105          171 :               specified_bounds, refs)
    4106           57 : {}
    4107              : 
    4108              : bool
    4109          924 : OpaqueType::can_resolve () const
    4110              : {
    4111          924 :   return get_ref () != get_ty_ref ();
    4112              : }
    4113              : 
    4114              : void
    4115            0 : OpaqueType::accept_vis (TyVisitor &vis)
    4116              : {
    4117            0 :   vis.visit (*this);
    4118            0 : }
    4119              : 
    4120              : void
    4121            0 : OpaqueType::accept_vis (TyConstVisitor &vis) const
    4122              : {
    4123            0 :   vis.visit (*this);
    4124            0 : }
    4125              : 
    4126              : std::string
    4127          259 : OpaqueType::as_string () const
    4128              : {
    4129          259 :   return get_name ();
    4130              : }
    4131              : 
    4132              : std::string
    4133         1891 : OpaqueType::get_name () const
    4134              : {
    4135         1891 :   return "impl " + raw_bounds_as_name ();
    4136              : }
    4137              : 
    4138              : BaseType *
    4139           57 : OpaqueType::clone () const
    4140              : {
    4141          114 :   return new OpaqueType (ident.locus, get_ref (), get_ty_ref (),
    4142           57 :                          get_specified_bounds (), get_combined_refs ());
    4143              : }
    4144              : 
    4145              : BaseType *
    4146         1458 : OpaqueType::resolve () const
    4147              : {
    4148         1458 :   TyVar var (get_ty_ref ());
    4149         1458 :   return var.get_tyty ();
    4150              : }
    4151              : 
    4152              : bool
    4153          280 : OpaqueType::is_equal (const BaseType &other) const
    4154              : {
    4155          280 :   auto other2 = static_cast<const OpaqueType &> (other);
    4156          280 :   if (can_resolve () != other2.can_resolve ())
    4157              :     return false;
    4158              : 
    4159          245 :   if (num_specified_bounds () != other.num_specified_bounds ())
    4160              :     return false;
    4161              : 
    4162          476 :   for (const auto &pred : specified_bounds)
    4163              :     {
    4164          238 :       bool found = false;
    4165          238 :       for (const auto &opred : other.get_specified_bounds ())
    4166              :         {
    4167          238 :           found = pred.is_equal (opred);
    4168          238 :           if (found)
    4169              :             break;
    4170              :         }
    4171              : 
    4172          238 :       if (!found)
    4173          280 :         return false;
    4174              :     }
    4175              : 
    4176              :   return true;
    4177          280 : }
    4178              : 
    4179              : // StrType
    4180              : 
    4181         4865 : StrType::StrType (HirId ref, std::set<HirId> refs)
    4182              :   : BaseType (ref, ref, KIND,
    4183         4865 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4184         9730 :               refs)
    4185         4865 : {}
    4186              : 
    4187         3816 : StrType::StrType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    4188              :   : BaseType (ref, ty_ref, KIND,
    4189         3816 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4190         7632 :               refs)
    4191         3816 : {}
    4192              : 
    4193              : std::string
    4194        98780 : StrType::get_name () const
    4195              : {
    4196        98780 :   return as_string ();
    4197              : }
    4198              : 
    4199              : BaseType *
    4200         3816 : StrType::clone () const
    4201              : {
    4202         3816 :   return new StrType (get_ref (), get_ty_ref (), get_combined_refs ());
    4203              : }
    4204              : 
    4205              : void
    4206            8 : StrType::accept_vis (TyVisitor &vis)
    4207              : {
    4208            8 :   vis.visit (*this);
    4209            8 : }
    4210              : 
    4211              : void
    4212         4695 : StrType::accept_vis (TyConstVisitor &vis) const
    4213              : {
    4214         4695 :   vis.visit (*this);
    4215         4695 : }
    4216              : 
    4217              : std::string
    4218       106841 : StrType::as_string () const
    4219              : {
    4220       106841 :   return "str";
    4221              : }
    4222              : 
    4223              : bool
    4224        14255 : StrType::is_equal (const BaseType &other) const
    4225              : {
    4226        14255 :   return get_kind () == other.get_kind ();
    4227              : }
    4228              : 
    4229              : // Never Type
    4230              : 
    4231         6012 : NeverType::NeverType (HirId ref, std::set<HirId> refs)
    4232              :   : BaseType (ref, ref, KIND,
    4233         6012 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4234        12024 :               refs)
    4235         6012 : {}
    4236              : 
    4237          769 : NeverType::NeverType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    4238              :   : BaseType (ref, ty_ref, KIND,
    4239          769 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4240         1538 :               refs)
    4241          769 : {}
    4242              : 
    4243              : std::string
    4244        16276 : NeverType::get_name () const
    4245              : {
    4246        16276 :   return as_string ();
    4247              : }
    4248              : 
    4249              : void
    4250            0 : NeverType::accept_vis (TyVisitor &vis)
    4251              : {
    4252            0 :   vis.visit (*this);
    4253            0 : }
    4254              : 
    4255              : void
    4256         4896 : NeverType::accept_vis (TyConstVisitor &vis) const
    4257              : {
    4258         4896 :   vis.visit (*this);
    4259         4896 : }
    4260              : 
    4261              : std::string
    4262        18632 : NeverType::as_string () const
    4263              : {
    4264        18632 :   return "!";
    4265              : }
    4266              : 
    4267              : BaseType *
    4268          769 : NeverType::clone () const
    4269              : {
    4270          769 :   return new NeverType (get_ref (), get_ty_ref (), get_combined_refs ());
    4271              : }
    4272              : 
    4273              : // placeholder type
    4274              : 
    4275            0 : PlaceholderType::PlaceholderType (std::string symbol, DefId id, HirId ref,
    4276              :                                   std::set<HirId> refs)
    4277              :   : BaseType (ref, ref, KIND,
    4278            0 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4279              :               refs),
    4280            0 :     symbol (symbol), defId (id)
    4281            0 : {}
    4282              : 
    4283            0 : PlaceholderType::PlaceholderType (std::string symbol, DefId id, HirId ref,
    4284              :                                   HirId ty_ref, std::set<HirId> refs)
    4285              :   : BaseType (ref, ty_ref, KIND,
    4286            0 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4287              :               refs),
    4288            0 :     symbol (symbol), defId (id)
    4289            0 : {}
    4290              : 
    4291              : std::string
    4292            0 : PlaceholderType::get_name () const
    4293              : {
    4294            0 :   return as_string ();
    4295              : }
    4296              : 
    4297              : std::string
    4298            0 : PlaceholderType::get_symbol () const
    4299              : {
    4300            0 :   return symbol;
    4301              : }
    4302              : 
    4303              : void
    4304            0 : PlaceholderType::accept_vis (TyVisitor &vis)
    4305              : {
    4306            0 :   vis.visit (*this);
    4307            0 : }
    4308              : 
    4309              : void
    4310            0 : PlaceholderType::accept_vis (TyConstVisitor &vis) const
    4311              : {
    4312            0 :   vis.visit (*this);
    4313            0 : }
    4314              : 
    4315              : std::string
    4316            0 : PlaceholderType::as_string () const
    4317              : {
    4318            0 :   return "<placeholder:" + (can_resolve () ? resolve ()->as_string () : "")
    4319            0 :          + ">";
    4320              : }
    4321              : 
    4322              : BaseType *
    4323            0 : PlaceholderType::clone () const
    4324              : {
    4325            0 :   return new PlaceholderType (get_symbol (), get_def_id (), get_ref (),
    4326            0 :                               get_ty_ref (), get_combined_refs ());
    4327              : }
    4328              : 
    4329              : bool
    4330            0 : PlaceholderType::can_resolve () const
    4331              : {
    4332            0 :   auto context = Resolver::TypeCheckContext::get ();
    4333              : 
    4334            0 :   BaseType *lookup = nullptr;
    4335            0 :   HirId mapping;
    4336              : 
    4337            0 :   if (!context->lookup_associated_type_mapping (get_ty_ref (), &mapping))
    4338              :     return false;
    4339              : 
    4340            0 :   if (!context->lookup_type (mapping, &lookup))
    4341              :     return false;
    4342              : 
    4343            0 :   return lookup != nullptr;
    4344              : }
    4345              : 
    4346              : BaseType *
    4347            0 : PlaceholderType::resolve () const
    4348              : {
    4349            0 :   auto context = Resolver::TypeCheckContext::get ();
    4350              : 
    4351            0 :   HirId mapping;
    4352            0 :   bool ok = context->lookup_associated_type_mapping (get_ty_ref (), &mapping);
    4353            0 :   rust_assert (ok);
    4354              : 
    4355            0 :   return TyVar (mapping).get_tyty ();
    4356              : }
    4357              : 
    4358              : bool
    4359            0 : PlaceholderType::is_equal (const BaseType &other) const
    4360              : {
    4361            0 :   if (get_kind () != other.get_kind ())
    4362              :     {
    4363            0 :       if (!can_resolve ())
    4364              :         return false;
    4365              : 
    4366            0 :       return resolve ()->is_equal (other);
    4367              :     }
    4368              : 
    4369            0 :   auto other2 = static_cast<const PlaceholderType &> (other);
    4370            0 :   return get_symbol ().compare (other2.get_symbol ()) == 0;
    4371            0 : }
    4372              : 
    4373              : DefId
    4374            0 : PlaceholderType::get_def_id () const
    4375              : {
    4376            0 :   return defId;
    4377              : }
    4378              : 
    4379              : // Projection type
    4380              : 
    4381         2592 : ProjectionType::ProjectionType (
    4382              :   HirId ref, BaseType *base, const Resolver::TraitReference *trait, DefId item,
    4383              :   std::vector<SubstitutionParamMapping> subst_refs, TyTy::BaseType *self,
    4384              :   SubstitutionArgumentMappings generic_arguments,
    4385              :   RegionConstraints region_constraints, std::set<HirId> refs,
    4386              :   size_t num_trait_substitutions)
    4387              :   : BaseType (ref, ref, KIND,
    4388         2592 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4389              :               std::move (refs)),
    4390              :     SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
    4391              :                      std::move (region_constraints)),
    4392         2592 :     base (base), trait (trait), item (item), self (self),
    4393         5184 :     num_trait_substitutions (num_trait_substitutions)
    4394         2592 : {}
    4395              : 
    4396        14515 : ProjectionType::ProjectionType (
    4397              :   HirId ref, HirId ty_ref, BaseType *base,
    4398              :   const Resolver::TraitReference *trait, DefId item,
    4399              :   std::vector<SubstitutionParamMapping> subst_refs, TyTy::BaseType *self,
    4400              :   SubstitutionArgumentMappings generic_arguments,
    4401              :   RegionConstraints region_constraints, std::set<HirId> refs,
    4402              :   size_t num_trait_substitutions)
    4403              :   : BaseType (ref, ty_ref, KIND,
    4404        14515 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4405              :               refs),
    4406              :     SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
    4407              :                      std::move (region_constraints)),
    4408        14515 :     base (base), trait (trait), item (item), self (self),
    4409        29030 :     num_trait_substitutions (num_trait_substitutions)
    4410        14515 : {}
    4411              : 
    4412              : std::string
    4413        43826 : ProjectionType::get_name () const
    4414              : {
    4415        43826 :   return as_string ();
    4416              : }
    4417              : 
    4418              : bool
    4419        52656 : ProjectionType::is_trait_position () const
    4420              : {
    4421        52656 :   return base == nullptr;
    4422              : }
    4423              : 
    4424              : const BaseType *
    4425            0 : ProjectionType::get () const
    4426              : {
    4427            0 :   rust_assert (base != nullptr);
    4428            0 :   return base;
    4429              : }
    4430              : 
    4431              : BaseType *
    4432        18325 : ProjectionType::get ()
    4433              : {
    4434        18325 :   rust_assert (base != nullptr);
    4435        18325 :   return base;
    4436              : }
    4437              : 
    4438              : const BaseType *
    4439        15871 : ProjectionType::get_self () const
    4440              : {
    4441        15871 :   return self;
    4442              : }
    4443              : 
    4444              : BaseType *
    4445        14530 : ProjectionType::get_self ()
    4446              : {
    4447        14530 :   return self;
    4448              : }
    4449              : 
    4450              : const Resolver::TraitReference *
    4451        35683 : ProjectionType::get_trait_ref () const
    4452              : {
    4453        35683 :   return trait;
    4454              : }
    4455              : 
    4456              : DefId
    4457        15596 : ProjectionType::get_item_defid () const
    4458              : {
    4459        15596 :   return item;
    4460              : }
    4461              : 
    4462              : void
    4463         7514 : ProjectionType::accept_vis (TyVisitor &vis)
    4464              : {
    4465         7514 :   vis.visit (*this);
    4466         7514 : }
    4467              : 
    4468              : void
    4469          327 : ProjectionType::accept_vis (TyConstVisitor &vis) const
    4470              : {
    4471          327 :   vis.visit (*this);
    4472          327 : }
    4473              : 
    4474              : std::string
    4475        49202 : ProjectionType::as_string () const
    4476              : {
    4477        98404 :   return "<Projection=" + subst_as_string ()
    4478       196808 :          + "::" + (base == nullptr ? "TRAIT_POSITION" : base->as_string ())
    4479       196808 :          + "::" + self->as_string () + ">";
    4480              : }
    4481              : 
    4482              : BaseType *
    4483        12388 : ProjectionType::clone () const
    4484              : {
    4485        12388 :   auto *cloned
    4486              :     = new ProjectionType (get_ref (), get_ty_ref (),
    4487         3230 :                           base != nullptr ? base->clone () : nullptr, trait,
    4488        12388 :                           item, clone_substs (), self->clone (), used_arguments,
    4489        37164 :                           region_constraints, get_combined_refs (),
    4490        40394 :                           num_trait_substitutions);
    4491        12388 :   cloned->inherit_bounds (get_specified_bounds ());
    4492        12388 :   return cloned;
    4493              : }
    4494              : 
    4495              : ProjectionType *
    4496         7514 : ProjectionType::handle_substitions (
    4497              :   SubstitutionArgumentMappings &subst_mappings)
    4498              : {
    4499         7514 :   ProjectionType *projection = static_cast<ProjectionType *> (clone ());
    4500         7514 :   projection->set_ty_ref (mappings.get_next_hir_id ());
    4501         7514 :   projection->used_arguments = subst_mappings;
    4502              : 
    4503         7514 :   auto context = Resolver::TypeCheckContext::get ();
    4504         7514 :   context->insert_implicit_type (projection->get_ty_ref (), projection);
    4505              : 
    4506        17523 :   for (auto &sub : projection->get_substs ())
    4507              :     {
    4508        10009 :       SubstitutionArg arg = SubstitutionArg::error ();
    4509        10009 :       bool ok
    4510        10009 :         = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg);
    4511        10009 :       if (ok)
    4512         9610 :         sub.fill_param_ty (subst_mappings, subst_mappings.get_locus ());
    4513              :     }
    4514              : 
    4515         7514 :   auto fty = projection->self;
    4516         7514 :   if (fty->get_kind () == TypeKind::PARAM)
    4517              :     {
    4518         5082 :       ParamType *p = static_cast<ParamType *> (fty);
    4519              : 
    4520         5082 :       SubstitutionArg arg = SubstitutionArg::error ();
    4521         5082 :       bool ok = subst_mappings.get_argument_for_symbol (p, &arg);
    4522         5082 :       if (ok)
    4523              :         {
    4524         4928 :           auto argt = arg.get_tyty ();
    4525         4928 :           bool arg_is_param = argt->get_kind () == TyTy::TypeKind::PARAM;
    4526         4928 :           bool arg_is_concrete = argt->get_kind () != TyTy::TypeKind::INFER;
    4527              : 
    4528         4928 :           if (arg_is_param || arg_is_concrete)
    4529              :             {
    4530         4600 :               auto new_field = argt->clone ();
    4531         4600 :               new_field->set_ref (fty->get_ref ());
    4532         4600 :               projection->self = new_field;
    4533              :             }
    4534              :           else
    4535              :             {
    4536          328 :               fty->set_ty_ref (argt->get_ref ());
    4537              :             }
    4538              :         }
    4539              :     }
    4540         2432 :   else if (fty->needs_generic_substitutions () || !fty->is_concrete ())
    4541              :     {
    4542         1641 :       BaseType *concrete
    4543         1641 :         = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings);
    4544              : 
    4545         1641 :       if (concrete == nullptr || concrete->get_kind () == TyTy::TypeKind::ERROR)
    4546              :         {
    4547            0 :           rust_error_at (subst_mappings.get_locus (),
    4548              :                          "Failed to resolve field substitution type: %s",
    4549            0 :                          fty->as_string ().c_str ());
    4550            0 :           return nullptr;
    4551              :         }
    4552              : 
    4553         1641 :       projection->self = concrete;
    4554              :     }
    4555              : 
    4556         7514 :   fty = projection->base;
    4557         7514 :   if (fty == nullptr)
    4558              :     return projection;
    4559              : 
    4560         3230 :   if (fty->get_kind () == TypeKind::PARAM)
    4561              :     {
    4562         2708 :       ParamType *p = static_cast<ParamType *> (fty);
    4563              : 
    4564         2708 :       SubstitutionArg arg = SubstitutionArg::error ();
    4565         2708 :       bool ok = subst_mappings.get_argument_for_symbol (p, &arg);
    4566         2708 :       if (ok)
    4567              :         {
    4568         2539 :           auto argt = arg.get_tyty ();
    4569         2539 :           bool arg_is_param = argt->get_kind () == TyTy::TypeKind::PARAM;
    4570         2539 :           bool arg_is_concrete = argt->get_kind () != TyTy::TypeKind::INFER;
    4571              : 
    4572         2539 :           if (arg_is_param || arg_is_concrete)
    4573              :             {
    4574         2522 :               auto new_field = argt->clone ();
    4575         2522 :               new_field->set_ref (fty->get_ref ());
    4576         2522 :               projection->base = new_field;
    4577              :             }
    4578              :           else
    4579              :             {
    4580           17 :               fty->set_ty_ref (argt->get_ref ());
    4581              :             }
    4582              :         }
    4583              :     }
    4584          522 :   else if (fty->needs_generic_substitutions () || !fty->is_concrete ())
    4585              :     {
    4586          142 :       BaseType *concrete
    4587          142 :         = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings);
    4588              : 
    4589          142 :       if (concrete == nullptr || concrete->get_kind () == TyTy::TypeKind::ERROR)
    4590              :         {
    4591            0 :           rust_error_at (subst_mappings.get_locus (),
    4592              :                          "Failed to resolve field substitution type: %s",
    4593            0 :                          fty->as_string ().c_str ());
    4594            0 :           return nullptr;
    4595              :         }
    4596              : 
    4597          142 :       projection->base = concrete;
    4598              :     }
    4599              : 
    4600              :   return projection;
    4601              : }
    4602              : 
    4603              : // DynObjectType
    4604              : 
    4605         4518 : DynamicObjectType::DynamicObjectType (
    4606              :   HirId ref, RustIdent ident, std::vector<TypeBoundPredicate> specified_bounds,
    4607              :   std::set<HirId> refs)
    4608         4518 :   : BaseType (ref, ref, KIND, ident, specified_bounds, refs)
    4609         4518 : {}
    4610              : 
    4611          650 : DynamicObjectType::DynamicObjectType (
    4612              :   HirId ref, HirId ty_ref, RustIdent ident,
    4613              :   std::vector<TypeBoundPredicate> specified_bounds, std::set<HirId> refs)
    4614          650 :   : BaseType (ref, ty_ref, KIND, ident, specified_bounds, refs)
    4615          650 : {}
    4616              : 
    4617              : void
    4618            0 : DynamicObjectType::accept_vis (TyVisitor &vis)
    4619              : {
    4620            0 :   vis.visit (*this);
    4621            0 : }
    4622              : 
    4623              : void
    4624           14 : DynamicObjectType::accept_vis (TyConstVisitor &vis) const
    4625              : {
    4626           14 :   vis.visit (*this);
    4627           14 : }
    4628              : 
    4629              : std::string
    4630         1105 : DynamicObjectType::as_string () const
    4631              : {
    4632         2210 :   return "dyn [" + raw_bounds_as_string () + "]";
    4633              : }
    4634              : 
    4635              : BaseType *
    4636          650 : DynamicObjectType::clone () const
    4637              : {
    4638          650 :   return new DynamicObjectType (get_ref (), get_ty_ref (), ident,
    4639         1300 :                                 specified_bounds, get_combined_refs ());
    4640              : }
    4641              : 
    4642              : std::string
    4643        51544 : DynamicObjectType::get_name () const
    4644              : {
    4645       103088 :   return "dyn [" + raw_bounds_as_name () + "]";
    4646              : }
    4647              : 
    4648              : bool
    4649        14353 : DynamicObjectType::is_equal (const BaseType &other) const
    4650              : {
    4651        14353 :   if (get_kind () != other.get_kind ())
    4652              :     return false;
    4653              : 
    4654         1340 :   if (num_specified_bounds () != other.num_specified_bounds ())
    4655              :     return false;
    4656              : 
    4657         2688 :   for (const auto &pred : specified_bounds)
    4658              :     {
    4659         1348 :       bool found = false;
    4660         1366 :       for (const auto &opred : other.get_specified_bounds ())
    4661              :         {
    4662         1366 :           found = pred.is_equal (opred);
    4663         1366 :           if (found)
    4664              :             break;
    4665              :         }
    4666              : 
    4667         1348 :       if (!found)
    4668        14353 :         return false;
    4669              :     }
    4670              : 
    4671              :   return true;
    4672              : }
    4673              : 
    4674              : const std::vector<
    4675              :   std::pair<const Resolver::TraitItemReference *, const TypeBoundPredicate *>>
    4676         1070 : DynamicObjectType::get_object_items () const
    4677              : {
    4678         1070 :   std::vector<
    4679              :     std::pair<const Resolver::TraitItemReference *, const TypeBoundPredicate *>>
    4680         1070 :     items;
    4681         2152 :   for (const TypeBoundPredicate &bound : get_specified_bounds ())
    4682              :     {
    4683         1082 :       const Resolver::TraitReference *trait = bound.get ();
    4684         1082 :       std::vector<const Resolver::TraitItemReference *> trait_items;
    4685         1082 :       trait->get_trait_items_and_supers (trait_items);
    4686              : 
    4687         2604 :       for (auto &item : trait_items)
    4688              :         {
    4689         1522 :           if (item->get_trait_item_type ()
    4690              :                 == Resolver::TraitItemReference::TraitItemType::FN
    4691         1522 :               && item->is_object_safe ())
    4692         1522 :             items.emplace_back (item, &bound);
    4693              :         }
    4694         1082 :     }
    4695         1070 :   return items;
    4696              : }
    4697              : 
    4698              : WARN_UNUSED_RESULT tl::optional<BaseType *>
    4699        21769 : try_get_box_inner_type (BaseType *base)
    4700              : {
    4701        21769 :   if (base->get_kind () != TypeKind::ADT)
    4702        14947 :     return tl::nullopt;
    4703              : 
    4704         6822 :   ADTType *adt = static_cast<ADTType *> (base);
    4705         6822 :   auto owned_box_lookup
    4706         6822 :     = Analysis::Mappings::get ().lookup_lang_item (LangItem::Kind::OWNED_BOX);
    4707              : 
    4708         6822 :   if (owned_box_lookup && adt->get_id () == *owned_box_lookup)
    4709              :     {
    4710            7 :       auto args = adt->get_substitution_arguments ();
    4711            7 :       if (!args.is_empty ())
    4712              :         {
    4713            7 :           auto inner = args.get_mappings ().front ().get_tyty ();
    4714            7 :           rust_assert (inner != nullptr);
    4715            7 :           return inner;
    4716              :         }
    4717            7 :     }
    4718         6815 :   return tl::nullopt;
    4719              : }
    4720              : 
    4721              : } // namespace TyTy
    4722              : } // 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.