LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-tyty.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.2 % 2244 1912
Test Date: 2026-09-19 16:22:48 Functions: 87.4 % 365 319
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        35038 : TypeKindFormat::to_string (TypeKind kind)
      43              : {
      44        35038 :   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        34924 :     case TypeKind::FNDEF:
      71        34924 :       return "FnDef";
      72              : 
      73            0 :     case TypeKind::FNPTR:
      74            0 :       return "FnPtr";
      75              : 
      76            5 :     case TypeKind::TUPLE:
      77            5 :       return "Tuple";
      78              : 
      79            1 :     case TypeKind::BOOL:
      80            1 :       return "Bool";
      81              : 
      82            0 :     case TypeKind::CHAR:
      83            0 :       return "Char";
      84              : 
      85           27 :     case TypeKind::INT:
      86           27 :       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      1127065 : BaseType::BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
     150              :                     std::set<HirId> refs)
     151      1127065 :   : TypeBoundsMappings ({}), kind (kind), ref (ref), ty_ref (ty_ref),
     152      1127065 :     orig_ref (ref), combined (refs), ident (ident),
     153      2254130 :     mappings (Analysis::Mappings::get ())
     154      1127065 : {}
     155              : 
     156      5816629 : BaseType::BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
     157              :                     std::vector<TypeBoundPredicate> specified_bounds,
     158              :                     std::set<HirId> refs)
     159      5816629 :   : TypeBoundsMappings (std::move (specified_bounds)), kind (kind), ref (ref),
     160      5816629 :     ty_ref (ty_ref), orig_ref (ref), combined (refs), ident (ident),
     161     11633258 :     mappings (Analysis::Mappings::get ())
     162      5816629 : {}
     163              : 
     164       108413 : BaseType::~BaseType () {}
     165              : 
     166              : HirId
     167     10954204 : BaseType::get_ref () const
     168              : {
     169     10954204 :   return ref;
     170              : }
     171              : 
     172              : void
     173       333761 : BaseType::set_ref (HirId id)
     174              : {
     175       333761 :   if (id != ref)
     176       276627 :     append_reference (ref);
     177       333761 :   ref = id;
     178       333761 : }
     179              : 
     180              : HirId
     181      9378655 : BaseType::get_ty_ref () const
     182              : {
     183      9378655 :   return ty_ref;
     184              : }
     185              : 
     186              : void
     187       234808 : BaseType::set_ty_ref (HirId id)
     188              : {
     189       234808 :   ty_ref = id;
     190       234808 : }
     191              : HirId
     192         7465 : BaseType::get_orig_ref () const
     193              : {
     194         7465 :   return orig_ref;
     195              : }
     196              : 
     197              : bool
     198       243856 : BaseType::is_equal (const BaseType &other) const
     199              : {
     200       243856 :   return get_kind () == other.get_kind ();
     201              : }
     202              : 
     203              : bool
     204       259512 : BaseType::is_unit () const
     205              : {
     206       259512 :   const TyTy::BaseType *x = destructure ();
     207       259512 :   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        12632 :     case TUPLE:
     239        12632 :       {
     240        12632 :         return x->as<const TupleType> ()->num_fields () == 0;
     241              :       }
     242              : 
     243       215836 :     case ADT:
     244       215836 :       {
     245       215836 :         auto adt = x->as<const ADTType> ();
     246       215836 :         if (adt->is_enum ())
     247              :           return false;
     248              : 
     249       214701 :         for (const auto &variant : adt->get_variants ())
     250              :           {
     251       170561 :             if (variant->num_fields () > 0)
     252       259512 :               return false;
     253              :           }
     254              : 
     255              :         return true;
     256              :       }
     257              :     }
     258              :   return false;
     259              : }
     260              : 
     261              : TypeKind
     262     59994314 : BaseType::get_kind () const
     263              : {
     264     59994314 :   return kind;
     265              : }
     266              : 
     267              : std::set<HirId>
     268      7030007 : BaseType::get_combined_refs () const
     269              : {
     270      7030007 :   return combined;
     271              : }
     272              : 
     273              : void
     274      3804503 : BaseType::append_reference (HirId id)
     275              : {
     276      3804503 :   combined.insert (id);
     277      3804503 : }
     278              : 
     279              : const RustIdent &
     280        90278 : BaseType::get_ident () const
     281              : {
     282        90278 :   return ident;
     283              : }
     284              : 
     285              : location_t
     286        38428 : BaseType::get_locus () const
     287              : {
     288        38428 :   return ident.locus;
     289              : }
     290              : 
     291              : bool
     292            5 : BaseType::unsize_to (const BaseType *target) const
     293              : {
     294            5 :   if (this->get_kind () == TyTy::TypeKind::DYNAMIC
     295            5 :       && target->get_kind () == TyTy::TypeKind::DYNAMIC)
     296              :     {
     297            1 :       const auto *source_dyn = this->as<const TyTy::DynamicObjectType> ();
     298            1 :       const auto *target_dyn = target->as<const TyTy::DynamicObjectType> ();
     299              : 
     300            1 :       const auto &source_bounds = source_dyn->get_specified_bounds ();
     301            1 :       const auto &target_bounds = target_dyn->get_specified_bounds ();
     302              : 
     303            1 :       if (source_bounds.empty () || target_bounds.empty ())
     304              :         return false;
     305              : 
     306            1 :       if (source_bounds.at (0).get_id () != target_bounds.at (0).get_id ())
     307              :         return false;
     308              : 
     309            2 :       for (const auto &t_bound : target_dyn->get_specified_bounds ())
     310              :         {
     311            1 :           bool found = false;
     312            1 :           for (const auto &s_bound : source_dyn->get_specified_bounds ())
     313              :             {
     314            1 :               if (s_bound.get_id () == t_bound.get_id ())
     315              :                 {
     316              :                   found = true;
     317              :                   break;
     318              :                 }
     319              :             }
     320            1 :           if (!found)
     321            5 :             return false;
     322              :         }
     323              :       return true;
     324              :     }
     325              : 
     326              :   // `T` -> `Trait`
     327            4 :   else if (target->get_kind () == TyTy::TypeKind::DYNAMIC)
     328              :     return true;
     329              : 
     330              :   // Ambiguous handling is below `T` -> `Trait`, because inference
     331              :   // variables can still implement `Unsize<Trait>` and nested
     332              :   // obligations will have the final say (likely deferred).
     333            3 :   else if (this->destructure ()->is<InferType> ()
     334            3 :            || target->destructure ()->is<InferType> ())
     335              :     return true;
     336              : 
     337              :   // `[T; n]` -> `[T]`
     338            3 :   else if (this->get_kind () == TyTy::TypeKind::ARRAY
     339            3 :            && target->get_kind () == TyTy::TypeKind::SLICE)
     340              :     return true;
     341              : 
     342              :   // `Struct<T>` -> `Struct<U>`
     343            2 :   else if (this->get_kind () == TyTy::TypeKind::ADT
     344            2 :            && target->get_kind () == TyTy::TypeKind::ADT)
     345              :     {
     346            1 :       const auto *source_adt = this->as<const TyTy::ADTType> ();
     347            1 :       const auto *target_adt = target->as<const TyTy::ADTType> ();
     348            1 :       return (source_adt->is_struct_struct () || source_adt->is_tuple_struct ())
     349            2 :              && source_adt->get_id () == target_adt->get_id ();
     350              :     }
     351              : 
     352              :   // `(.., T)` -> `(.., U)`
     353            1 :   else if (this->get_kind () == TyTy::TypeKind::TUPLE
     354            1 :            && target->get_kind () == TyTy::TypeKind::TUPLE)
     355              :     {
     356            1 :       const auto *source_tuple = this->as<const TyTy::TupleType> ();
     357            1 :       const auto *target_tuple = target->as<const TyTy::TupleType> ();
     358            1 :       return source_tuple->get_subst_argument_mappings ().size ()
     359            1 :              == target_tuple->get_subst_argument_mappings ().size ();
     360              :     }
     361              :   return false;
     362              : }
     363              : 
     364              : // FIXME this is missing locus
     365              : bool
     366        76635 : BaseType::satisfies_bound (const TypeBoundPredicate &predicate, bool emit_error)
     367              : {
     368              :   // see:
     369              :   // https://github.com/rust-lang/rust/blob/e1884a8e3c3e813aada8254edfa120e85bf5ffca/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs#L673
     370        76635 :   if (auto unsize_id = mappings.lookup_lang_item (Rust::LangItem::Kind::UNSIZE))
     371              :     {
     372           60 :       if (predicate.get_id () == unsize_id)
     373              :         {
     374            5 :           const auto &args = predicate.get_substitution_arguments ();
     375            5 :           rust_assert (args.size () == 2 && "Unsize<U>");
     376              : 
     377              :           // When this target is defined as `U`, it does not give us the
     378              :           // realized argument type. Instead, it returns `PARAM`.
     379            5 :           TyTy::BaseType *target
     380            5 :             = args.get_mappings ().at (1).get_param_ty ()->resolve ();
     381              : 
     382            5 :           return this->unsize_to (target);
     383              :         }
     384              :     }
     385              : 
     386        76630 :   const Resolver::TraitReference *query = predicate.get ();
     387        79427 :   for (const auto &bound : specified_bounds)
     388              :     {
     389        26411 :       const Resolver::TraitReference *item = bound.get ();
     390        26411 :       if (item->satisfies_bound (*query))
     391        76635 :         return true;
     392              :     }
     393              : 
     394        53016 :   if (destructure ()->is<InferType> ())
     395              :     return true;
     396              : 
     397        52362 :   bool satisfied = false;
     398        52362 :   auto tref = predicate.get ();
     399        52362 :   auto probed
     400        52362 :     = Resolver::TypeBoundsProbe::Probe (this, tref->get_hir_trait_ref ());
     401        59451 :   for (const auto &b : probed)
     402              :     {
     403        52366 :       const Resolver::TraitReference *bound = b.first;
     404        52366 :       if (bound->satisfies_bound (*query))
     405              :         {
     406              :           satisfied = true;
     407              :           break;
     408              :         }
     409              :     }
     410              : 
     411        52362 :   if (!satisfied)
     412              :     return false;
     413              : 
     414        45290 :   for (const auto &b : probed)
     415              :     {
     416        45286 :       const Resolver::TraitReference *bound = b.first;
     417        45286 :       if (!bound->is_equal (*query))
     418            9 :         continue;
     419              : 
     420              :       // builtin ones have no impl-block this needs fixed and use a builtin
     421              :       // node of somekind
     422        45277 :       if (b.second == nullptr)
     423              :         {
     424            0 :           return predicate.get_polarity () == BoundPolarity::RegularBound;
     425              :         }
     426              :       else
     427              :         {
     428        45277 :           const auto &impl = *(b.second);
     429        45277 :           if (predicate.get_polarity () != impl.get_polarity ())
     430            4 :             continue;
     431              :         }
     432              : 
     433              :       // need to check that associated types can match as well
     434        45273 :       const HIR::ImplBlock &impl = *(b.second);
     435        76950 :       for (const auto &item : impl.get_impl_items ())
     436              :         {
     437        31679 :           bool is_associated_type = item->get_impl_item_type ()
     438        31679 :                                     == HIR::ImplItem::ImplItemType::TYPE_ALIAS;
     439        31679 :           if (!is_associated_type)
     440        31656 :             continue;
     441              : 
     442         5613 :           std::string item_name = item->get_impl_item_name ();
     443         5613 :           tl::optional<TypeBoundPredicateItem> lookup
     444         5613 :             = predicate.lookup_associated_item (item_name);
     445         5613 :           if (!lookup.has_value ())
     446              :             return false;
     447              : 
     448         5613 :           const auto *item_ref = lookup->get_raw_item ();
     449         5613 :           TyTy::BaseType *bound_ty = item_ref->get_tyty ();
     450         5613 :           const auto &bindings
     451         5613 :             = predicate.get_substitution_arguments ().get_binding_args ();
     452         5613 :           auto bind_it = bindings.find (item_name);
     453         5613 :           if (bind_it != bindings.end ())
     454           64 :             bound_ty = bind_it->second;
     455         5549 :           else if (auto *proj = bound_ty->try_as<TyTy::ProjectionType> ())
     456         5549 :             if (proj->is_trait_position ())
     457         5549 :               continue;
     458              : 
     459           64 :           TyTy::BaseType *impl_item_ty = nullptr;
     460           64 :           Analysis::NodeMapping i = item->get_impl_mappings ();
     461           64 :           bool query_ok = Resolver::query_type (i.get_hirid (), &impl_item_ty);
     462           64 :           if (!query_ok)
     463              :             return false;
     464              : 
     465              :           // If the impl alias still depends on the impl's own generics
     466              :           // defer the binding check to monomorphization.
     467              :           //
     468              :           // The receiver-vs-impl substitution that pins T = i32 only
     469              :           // happens with a committing unification at the call site
     470           64 :           bool impl_item_concrete = impl_item_ty->is_concrete ();
     471           64 :           if (auto *p = impl_item_ty->try_as<TyTy::ProjectionType> ())
     472           64 :             if (!p->is_trait_position () && p->get () != nullptr)
     473           64 :               impl_item_concrete = p->get ()->is_concrete ();
     474           64 :           if (!impl_item_concrete)
     475           41 :             continue;
     476              : 
     477           46 :           if (!Resolver::types_compatable (
     478           23 :                 TyTy::TyWithLocation (bound_ty, predicate.get_locus ()),
     479           23 :                 TyTy::TyWithLocation (impl_item_ty, item->get_locus ()),
     480           23 :                 mappings.lookup_location (get_ref ()), false /*emit-error*/,
     481              :                 false /*check-bounds*/))
     482              :             return false;
     483         5613 :         }
     484              : 
     485              :       return true;
     486              :     }
     487              : 
     488              :   return false;
     489        52362 : }
     490              : 
     491              : bool
     492        54788 : BaseType::bounds_compatible (BaseType &other, location_t locus, bool emit_error)
     493              : {
     494        54788 :   std::vector<std::reference_wrapper<const TypeBoundPredicate>>
     495        54788 :     unsatisfied_bounds;
     496       113223 :   for (auto &bound : get_specified_bounds ())
     497              :     {
     498        58435 :       if (!other.satisfies_bound (bound, emit_error))
     499         7086 :         unsatisfied_bounds.push_back (bound);
     500              :     }
     501              : 
     502              :   // lets emit a single error for this
     503        54788 :   if (unsatisfied_bounds.size () > 0)
     504              :     {
     505         7085 :       rich_location r (line_table, locus);
     506         7085 :       std::string missing_preds;
     507        14171 :       for (size_t i = 0; i < unsatisfied_bounds.size (); i++)
     508              :         {
     509         7086 :           const TypeBoundPredicate &pred = unsatisfied_bounds.at (i);
     510         7086 :           r.add_range (pred.get_locus ());
     511        14172 :           missing_preds += pred.get_name ();
     512              : 
     513         7086 :           bool have_next = (i + 1) < unsatisfied_bounds.size ();
     514         7086 :           if (have_next)
     515            1 :             missing_preds += ", ";
     516              :         }
     517              : 
     518         7085 :       if (emit_error)
     519              :         {
     520           21 :           rust_error_at (r, ErrorCode::E0277,
     521              :                          "bounds not satisfied for %s %qs is not satisfied",
     522           42 :                          other.get_name ().c_str (), missing_preds.c_str ());
     523              :           // rust_assert (!emit_error);
     524              :         }
     525         7085 :     }
     526              : 
     527        54788 :   return unsatisfied_bounds.size () == 0;
     528        54788 : }
     529              : 
     530              : void
     531        14752 : BaseType::inherit_bounds (const BaseType &other)
     532              : {
     533        14752 :   inherit_bounds (other.get_specified_bounds ());
     534        14752 : }
     535              : 
     536              : void
     537        24464 : BaseType::inherit_bound (const TypeBoundPredicate &bound)
     538              : {
     539        24464 :   add_bound (bound);
     540        24464 : }
     541              : 
     542              : void
     543        43351 : BaseType::inherit_bounds (
     544              :   const std::vector<TyTy::TypeBoundPredicate> &specified_bounds)
     545              : {
     546        74862 :   for (auto &bound : specified_bounds)
     547              :     {
     548        31511 :       add_bound (bound);
     549              :     }
     550        43351 : }
     551              : 
     552              : BaseType *
     553        14886 : BaseType::get_root ()
     554              : {
     555        19012 :   TyTy::BaseType *root = this;
     556              : 
     557        19012 :   if (const auto r = root->try_as<const ReferenceType> ())
     558              :     {
     559         3134 :       root = r->get_base ()->get_root ();
     560              :     }
     561        15878 :   else if (const auto r = root->try_as<const PointerType> ())
     562              :     {
     563          656 :       root = r->get_base ()->get_root ();
     564              :     }
     565              :   // these are an unsize
     566        15222 :   else if (const auto r = root->try_as<const SliceType> ())
     567              :     {
     568          336 :       root = r->get_element_type ()->get_root ();
     569              :     }
     570              :   //  else if (const auto r = root->try_as<const ArrayType> ())
     571              :   //    {
     572              :   //      root = r->get_element_type ()->get_root ();
     573              :   //    }
     574              : 
     575        14886 :   return root;
     576              : }
     577              : 
     578              : BaseType *
     579      1973375 : BaseType::destructure ()
     580              : {
     581      1973375 :   int recurisve_ops = 0;
     582      1973375 :   BaseType *x = this;
     583      2103003 :   while (true)
     584              :     {
     585      2103003 :       if (recurisve_ops++ >= rust_max_recursion_depth)
     586              :         {
     587            0 :           rust_error_at (
     588              :             UNDEF_LOCATION,
     589              :             "%<recursion depth%> count exceeds limit of %i (use "
     590              :             "%<frust-max-recursion-depth=%> to increase the limit)",
     591              :             rust_max_recursion_depth);
     592            0 :           return new ErrorType (get_ref ());
     593              :         }
     594              : 
     595      2103003 :       if (auto p = x->try_as<ParamType> ())
     596              :         {
     597       202444 :           auto pr = p->resolve ();
     598       202444 :           if (pr == x)
     599              :             return pr;
     600              : 
     601              :           x = pr;
     602              :         }
     603      1900559 :       else if (x->get_kind () == TypeKind::CONST)
     604              :         {
     605         8227 :           auto p = x->as_const_type ();
     606         8227 :           if (p->const_kind () == BaseConstType::ConstKind::Decl)
     607              :             {
     608          701 :               auto decl = static_cast<ConstParamType *> (p);
     609          701 :               auto pr = decl->resolve ();
     610          701 :               if (pr == x)
     611              :                 return pr;
     612              : 
     613              :               x = pr;
     614              :             }
     615              :           else
     616              :             {
     617              :               return x;
     618              :             }
     619              :         }
     620      1892332 :       else if (auto p = x->try_as<PlaceholderType> ())
     621              :         {
     622            0 :           if (!p->can_resolve ())
     623              :             return p;
     624              : 
     625            0 :           x = p->resolve ();
     626              :         }
     627              :       else
     628              :         {
     629              :           return x;
     630              :         }
     631              :     }
     632              : 
     633              :   return x;
     634              : }
     635              : 
     636              : const BaseType *
     637      2618872 : BaseType::destructure () const
     638              : {
     639      2618872 :   int recurisve_ops = 0;
     640      2618872 :   const BaseType *x = this;
     641      2831238 :   while (true)
     642              :     {
     643      2831238 :       if (recurisve_ops++ >= rust_max_recursion_depth)
     644              :         {
     645            0 :           rust_error_at (
     646              :             UNDEF_LOCATION,
     647              :             "%<recursion depth%> count exceeds limit of %i (use "
     648              :             "%<frust-max-recursion-depth=%> to increase the limit)",
     649              :             rust_max_recursion_depth);
     650            0 :           return new ErrorType (get_ref ());
     651              :         }
     652              : 
     653      2831238 :       if (auto p = x->try_as<const ParamType> ())
     654              :         {
     655       389602 :           auto pr = p->resolve ();
     656       389602 :           if (pr == x)
     657              :             return pr;
     658              : 
     659              :           x = pr;
     660              :         }
     661      2441636 :       else if (x->get_kind () == TypeKind::CONST)
     662              :         {
     663         8202 :           auto p = x->as_const_type ();
     664         8202 :           if (p->const_kind () == BaseConstType::ConstKind::Decl)
     665              :             {
     666         1370 :               auto decl = static_cast<const ConstParamType *> (p);
     667         1370 :               auto pr = decl->resolve ();
     668         1370 :               if (pr == x)
     669              :                 return pr;
     670              : 
     671              :               x = pr;
     672              :             }
     673              :           else
     674              :             {
     675              :               return x;
     676              :             }
     677              :         }
     678      2433434 :       else if (auto p = x->try_as<const PlaceholderType> ())
     679              :         {
     680            0 :           if (!p->can_resolve ())
     681              :             return p;
     682              : 
     683            0 :           x = p->resolve ();
     684              :         }
     685      2433434 :       else if (auto p = x->try_as<const OpaqueType> ())
     686              :         {
     687          765 :           auto pr = p->resolve ();
     688          765 :           if (pr == x)
     689              :             return pr;
     690              : 
     691              :           x = pr;
     692              :         }
     693              :       else
     694              :         {
     695              :           return x;
     696              :         }
     697              :     }
     698              : 
     699              :   return x;
     700              : }
     701              : 
     702              : BaseType *
     703        18049 : BaseType::monomorphized_clone () const
     704              : {
     705        18049 :   const TyTy::BaseType *x = destructure ();
     706              : 
     707        18049 :   if (auto arr = x->try_as<const ArrayType> ())
     708              :     {
     709          270 :       TyVar elm = arr->get_var_element_type ().monomorphized_clone ();
     710          540 :       return new ArrayType (arr->get_ref (), arr->get_ty_ref (), ident.locus,
     711          270 :                             arr->get_capacity_var (), elm,
     712          270 :                             arr->get_combined_refs ());
     713              :     }
     714        17779 :   else if (auto slice = x->try_as<const SliceType> ())
     715              :     {
     716          136 :       TyVar elm = slice->get_var_element_type ().monomorphized_clone ();
     717          136 :       return new SliceType (slice->get_ref (), slice->get_ty_ref (),
     718          136 :                             ident.locus, elm, slice->get_combined_refs ());
     719              :     }
     720        17643 :   else if (auto ptr = x->try_as<const PointerType> ())
     721              :     {
     722          643 :       TyVar elm = ptr->get_var_element_type ().monomorphized_clone ();
     723          643 :       return new PointerType (ptr->get_ref (), ptr->get_ty_ref (), elm,
     724          643 :                               ptr->mutability (), ptr->get_combined_refs ());
     725              :     }
     726        17000 :   else if (auto ref = x->try_as<const ReferenceType> ())
     727              :     {
     728          298 :       TyVar elm = ref->get_var_element_type ().monomorphized_clone ();
     729          298 :       return new ReferenceType (ref->get_ref (), ref->get_ty_ref (), elm,
     730          596 :                                 ref->mutability (), ref->get_region (),
     731          894 :                                 ref->get_combined_refs ());
     732              :     }
     733        16702 :   else if (auto tuple = x->try_as<const TupleType> ())
     734              :     {
     735          529 :       std::vector<TyVar> cloned_fields;
     736          951 :       for (const auto &f : tuple->get_fields ())
     737          422 :         cloned_fields.push_back (f.monomorphized_clone ());
     738              : 
     739          529 :       return new TupleType (tuple->get_ref (), tuple->get_ty_ref (),
     740          529 :                             ident.locus, cloned_fields,
     741          529 :                             tuple->get_combined_refs ());
     742          529 :     }
     743        16173 :   else if (auto fn = x->try_as<const FnType> ())
     744              :     {
     745            0 :       std::vector<TyTy::FnParam> cloned_params;
     746            0 :       for (auto &p : fn->get_params ())
     747            0 :         cloned_params.push_back (p.monomorphized_clone ());
     748              : 
     749            0 :       BaseType *retty = fn->get_return_type ()->monomorphized_clone ();
     750            0 :       return new FnType (fn->get_ref (), fn->get_ty_ref (), fn->get_id (),
     751            0 :                          fn->get_identifier (), fn->ident, fn->get_flags (),
     752              :                          fn->get_abi (), std::move (cloned_params), retty,
     753            0 :                          fn->clone_substs (), fn->get_substitution_arguments (),
     754              :                          fn->get_region_constraints (),
     755            0 :                          fn->get_combined_refs ());
     756            0 :     }
     757        16173 :   else if (auto fn = x->try_as<const FnPtr> ())
     758              :     {
     759            2 :       std::vector<TyVar> cloned_params;
     760            4 :       for (auto &p : fn->get_params ())
     761            2 :         cloned_params.push_back (p.monomorphized_clone ());
     762              : 
     763            2 :       TyVar retty = fn->get_var_return_type ().monomorphized_clone ();
     764            2 :       return new FnPtr (fn->get_ref (), fn->get_ty_ref (), ident.locus,
     765              :                         std::move (cloned_params), retty, fn->get_abi (),
     766            2 :                         fn->get_unsafety (), fn->get_combined_refs ());
     767            2 :     }
     768        16171 :   else if (auto adt = x->try_as<const ADTType> ())
     769              :     {
     770         2234 :       std::vector<VariantDef *> cloned_variants;
     771         5920 :       for (auto &variant : adt->get_variants ())
     772         3686 :         cloned_variants.push_back (variant->monomorphized_clone ());
     773              : 
     774         2234 :       return new ADTType (adt->get_id (), adt->get_ref (), adt->get_ty_ref (),
     775         4468 :                           adt->get_identifier (), adt->ident,
     776              :                           adt->get_adt_kind (), cloned_variants,
     777         2234 :                           adt->clone_substs (), adt->get_repr_options (),
     778              :                           adt->get_used_arguments (),
     779              :                           adt->get_region_constraints (),
     780         8936 :                           adt->get_combined_refs ());
     781         2234 :     }
     782        13937 :   else if (auto proj = x->try_as<const ProjectionType> ())
     783              :     {
     784          220 :       TyTy::ProjectionType *xx
     785          220 :         = static_cast<TyTy::ProjectionType *> (proj->clone ());
     786          220 :       return Resolver::normalize_projection (xx, UNKNOWN_LOCATION /*FIXME*/,
     787          220 :                                              false, true);
     788              :     }
     789              :   else
     790              :     {
     791        13717 :       return x->clone ();
     792              :     }
     793              : 
     794              :   rust_unreachable ();
     795              :   return nullptr;
     796              : }
     797              : 
     798              : std::string
     799        35038 : BaseType::mappings_str () const
     800              : {
     801        70076 :   std::string buffer = "Ref: " + std::to_string (get_ref ())
     802       105114 :                        + " TyRef: " + std::to_string (get_ty_ref ());
     803        35038 :   buffer += "[";
     804        52729 :   for (auto &ref : combined)
     805        53073 :     buffer += std::to_string (ref) + ",";
     806        35038 :   buffer += "]";
     807        70076 :   return "(" + buffer + ")";
     808        35038 : }
     809              : 
     810              : std::string
     811        15894 : BaseType::debug_str () const
     812              : {
     813              :   // return TypeKindFormat::to_string (get_kind ()) + ":" + as_string () + ":"
     814              :   //        + mappings_str () + ":" + bounds_as_string ();
     815        15894 :   return get_name ();
     816              : }
     817              : 
     818              : void
     819         2167 : BaseType::debug () const
     820              : {
     821         2167 :   rust_debug ("[%p] %s", static_cast<const void *> (this),
     822              :               debug_str ().c_str ());
     823         2167 : }
     824              : 
     825              : const TyTy::BaseType *
     826        34678 : BaseType::contains_infer () const
     827              : {
     828        36030 :   const TyTy::BaseType *x = destructure ();
     829              : 
     830        36030 :   if (auto fn = x->try_as<const FnType> ())
     831              :     {
     832            0 :       for (const auto &param : fn->get_params ())
     833              :         {
     834            0 :           auto infer = param.get_type ()->contains_infer ();
     835            0 :           if (infer)
     836        34678 :             return infer;
     837              :         }
     838            0 :       return fn->get_return_type ()->contains_infer ();
     839              :     }
     840        36030 :   else if (auto fn = x->try_as<const FnPtr> ())
     841              :     {
     842           26 :       for (const auto &param : fn->get_params ())
     843              :         {
     844           12 :           auto infer = param.get_tyty ()->contains_infer ();
     845           12 :           if (infer)
     846        34678 :             return infer;
     847              :         }
     848           14 :       return fn->get_return_type ()->contains_infer ();
     849              :     }
     850        36016 :   else if (auto adt = x->try_as<const ADTType> ())
     851              :     {
     852         5976 :       for (auto &variant : adt->get_variants ())
     853              :         {
     854         3411 :           bool is_num_variant
     855         3411 :             = variant->get_variant_type () == VariantDef::VariantType::NUM;
     856         3411 :           bool is_unit_variant
     857         3411 :             = variant->get_variant_type () == VariantDef::VariantType::UNIT;
     858         3411 :           if (is_num_variant || is_unit_variant)
     859         1344 :             continue;
     860              : 
     861         6650 :           for (auto &field : variant->get_fields ())
     862              :             {
     863         4710 :               const BaseType *field_type = field->get_field_type ();
     864         4710 :               auto infer = (field_type->contains_infer ());
     865         4710 :               if (infer)
     866        34678 :                 return infer;
     867              :             }
     868              :         }
     869              :       return nullptr;
     870              :     }
     871        33324 :   else if (auto arr = x->try_as<const ArrayType> ())
     872              :     {
     873          449 :       auto type_infer = (arr->get_element_type ()->contains_infer ());
     874          449 :       if (type_infer)
     875              :         return type_infer;
     876          440 :       return arr->get_capacity ()->contains_infer ();
     877              :     }
     878        32875 :   else if (auto slice = x->try_as<const SliceType> ())
     879              :     {
     880          173 :       return slice->get_element_type ()->contains_infer ();
     881              :     }
     882        32702 :   else if (auto ptr = x->try_as<const PointerType> ())
     883              :     {
     884          536 :       return ptr->get_base ()->contains_infer ();
     885              :     }
     886        32166 :   else if (auto ref = x->try_as<const ReferenceType> ())
     887              :     {
     888          189 :       return ref->get_base ()->contains_infer ();
     889              :     }
     890        31977 :   else if (auto tuple = x->try_as<const TupleType> ())
     891              :     {
     892         8245 :       for (size_t i = 0; i < tuple->num_fields (); i++)
     893              :         {
     894          356 :           auto infer = (tuple->get_field (i)->contains_infer ());
     895          356 :           if (infer)
     896              :             return infer;
     897              :         }
     898              :       return nullptr;
     899              :     }
     900        23864 :   else if (auto closure = x->try_as<const ClosureType> ())
     901              :     {
     902            0 :       auto infer = (closure->get_parameters ().contains_infer ());
     903            0 :       if (infer)
     904              :         return infer;
     905            0 :       return closure->get_result_type ().contains_infer ();
     906              :     }
     907        23864 :   else if (x->is<InferType> ())
     908              :     {
     909              :       return x;
     910              :     }
     911        20805 :   else if (x->get_kind () == TyTy::TypeKind::CONST)
     912              :     {
     913          440 :       if (x->as_const_type ()->const_kind () == BaseConstType::Infer)
     914              :         {
     915            8 :           return x;
     916              :         }
     917              :     }
     918              : 
     919              :   return nullptr;
     920              : }
     921              : 
     922              : bool
     923      1390573 : BaseType::is_concrete () const
     924              : {
     925      1650491 :   const TyTy::BaseType *x = destructure ();
     926              : 
     927      1650491 :   if (x->is<ParamType> ())
     928              :     {
     929              :       return false;
     930              :     }
     931      1490336 :   else if (x->get_kind () == TyTy::TypeKind::CONST)
     932              :     {
     933         7103 :       auto p = x->as_const_type ();
     934         7103 :       if (p->const_kind () == BaseConstType::ConstKind::Decl)
     935              :         return false;
     936              : 
     937              :       return true;
     938              :     }
     939      1483233 :   else if (x->is<ProjectionType> ())
     940              :     {
     941         9443 :       const auto p = x->as<const TyTy::ProjectionType> ();
     942         9443 :       return p->get_self ()->is_concrete ();
     943              :     }
     944              :   // placeholder is a special case for this case when it is not resolvable
     945              :   // it means we its just an empty placeholder associated type which is
     946              :   // concrete
     947      1473790 :   else if (x->is<PlaceholderType> ())
     948              :     {
     949              :       return true;
     950              :     }
     951      1473790 :   else if (auto fn = x->try_as<const FnType> ())
     952              :     {
     953        22152 :       for (const auto &param : fn->get_params ())
     954              :         {
     955        14150 :           if (!param.get_type ()->is_concrete ())
     956      1390573 :             return false;
     957              :         }
     958         8002 :       return fn->get_return_type ()->is_concrete ();
     959              :     }
     960      1464272 :   else if (auto fn = x->try_as<const FnPtr> ())
     961              :     {
     962         2590 :       for (const auto &param : fn->get_params ())
     963              :         {
     964          116 :           if (!param.get_tyty ()->is_concrete ())
     965      1390573 :             return false;
     966              :         }
     967         2474 :       return fn->get_return_type ()->is_concrete ();
     968              :     }
     969      1461791 :   else if (auto adt = x->try_as<const ADTType> ())
     970              :     {
     971       166193 :       if (adt->is_unit ())
     972        32609 :         return !adt->needs_substitution ();
     973              : 
     974       310568 :       for (auto &variant : adt->get_variants ())
     975              :         {
     976       186003 :           bool is_num_variant
     977       186003 :             = variant->get_variant_type () == VariantDef::VariantType::NUM;
     978       186003 :           bool is_unit_variant
     979       186003 :             = variant->get_variant_type () == VariantDef::VariantType::UNIT;
     980       186003 :           if (is_num_variant || is_unit_variant)
     981        55675 :             continue;
     982              : 
     983       364658 :           for (auto &field : variant->get_fields ())
     984              :             {
     985       243349 :               const BaseType *field_type = field->get_field_type ();
     986       243349 :               if (!field_type->is_concrete ())
     987      1390573 :                 return false;
     988              :             }
     989              :         }
     990              :       return true;
     991              :     }
     992      1295598 :   else if (auto arr = x->try_as<const ArrayType> ())
     993              :     {
     994         3717 :       return arr->get_element_type ()->is_concrete ()
     995         3717 :              && arr->get_capacity ()->is_concrete ();
     996              :     }
     997      1291881 :   else if (auto slice = x->try_as<const SliceType> ())
     998              :     {
     999        10446 :       return slice->get_element_type ()->is_concrete ();
    1000              :     }
    1001      1281435 :   else if (auto ptr = x->try_as<const PointerType> ())
    1002              :     {
    1003        14927 :       return ptr->get_base ()->is_concrete ();
    1004              :     }
    1005      1266508 :   else if (auto ref = x->try_as<const ReferenceType> ())
    1006              :     {
    1007       214626 :       return ref->get_base ()->is_concrete ();
    1008              :     }
    1009      1051882 :   else if (auto tuple = x->try_as<const TupleType> ())
    1010              :     {
    1011        20889 :       for (size_t i = 0; i < tuple->num_fields (); i++)
    1012              :         {
    1013         2898 :           if (!tuple->get_field (i)->is_concrete ())
    1014              :             return false;
    1015              :         }
    1016              :       return true;
    1017              :     }
    1018      1033547 :   else if (auto closure = x->try_as<const ClosureType> ())
    1019              :     {
    1020          259 :       if (closure->get_parameters ().is_concrete ())
    1021              :         return false;
    1022            0 :       return closure->get_result_type ().is_concrete ();
    1023              :     }
    1024      3038417 :   else if (x->is<InferType> () || x->is<BoolType> () || x->is<CharType> ()
    1025      1823632 :            || x->is<IntType> () || x->is<UintType> () || x->is<FloatType> ()
    1026       292362 :            || x->is<USizeType> () || x->is<ISizeType> () || x->is<NeverType> ()
    1027        15840 :            || x->is<StrType> () || x->is<DynamicObjectType> ()
    1028      1033294 :            || x->is<ErrorType> ())
    1029              :     {
    1030              :       return true;
    1031              :     }
    1032              : 
    1033              :   return false;
    1034              : }
    1035              : 
    1036              : bool
    1037           32 : BaseType::is_zero_sized () const
    1038              : {
    1039           32 :   const TyTy::BaseType *x = destructure ();
    1040           32 :   switch (x->get_kind ())
    1041              :     {
    1042              :     // primitives that are always non-zero size
    1043              :     case FNPTR:
    1044              :     case FNDEF:
    1045              :     case SLICE:
    1046              :     case POINTER:
    1047              :     case REF:
    1048              :     case CLOSURE:
    1049              :     case INFER:
    1050              :     case BOOL:
    1051              :     case CHAR:
    1052              :     case INT:
    1053              :     case UINT:
    1054              :     case FLOAT:
    1055              :     case USIZE:
    1056              :     case ISIZE:
    1057              :     case OPAQUE:
    1058              :     case STR:
    1059              :     case DYNAMIC:
    1060              :     case CONST:
    1061              :     case PARAM:
    1062              :     case PROJECTION:
    1063              :     case PLACEHOLDER:
    1064              :     case ERROR:
    1065              :       return false;
    1066              : 
    1067            0 :     case NEVER:
    1068            0 :       return true;
    1069            1 :     case TUPLE:
    1070            1 :       {
    1071            1 :         const TupleType *tuple_ty = static_cast<const TupleType *> (x);
    1072            1 :         return tuple_ty->is_zero_sized ();
    1073              :       }
    1074            2 :     case ARRAY:
    1075            2 :       {
    1076            2 :         const ArrayType *array_ty = static_cast<const ArrayType *> (x);
    1077            2 :         return array_ty->is_zero_sized ();
    1078              :       }
    1079            2 :     case ADT:
    1080            2 :       {
    1081            2 :         const ADTType *adt_ty = static_cast<const ADTType *> (x);
    1082            2 :         return adt_ty->is_zero_sized ();
    1083              :       }
    1084              :     }
    1085              :   return false;
    1086              : }
    1087              : 
    1088              : bool
    1089       208642 : BaseType::has_substitutions_defined () const
    1090              : {
    1091       208642 :   const auto x = this;
    1092       208642 :   switch (x->get_kind ())
    1093              :     {
    1094              :     case INFER:
    1095              :     case BOOL:
    1096              :     case CHAR:
    1097              :     case INT:
    1098              :     case UINT:
    1099              :     case FLOAT:
    1100              :     case USIZE:
    1101              :     case ISIZE:
    1102              :     case NEVER:
    1103              :     case STR:
    1104              :     case DYNAMIC:
    1105              :     case ERROR:
    1106              :     case FNPTR:
    1107              :     case ARRAY:
    1108              :     case SLICE:
    1109              :     case POINTER:
    1110              :     case REF:
    1111              :     case TUPLE:
    1112              :     case PARAM:
    1113              :     case PLACEHOLDER:
    1114              :     case CONST:
    1115              :     case OPAQUE:
    1116              :       return false;
    1117              : 
    1118          214 :     case PROJECTION:
    1119          214 :       {
    1120          214 :         const ProjectionType &p = *static_cast<const ProjectionType *> (x);
    1121          214 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (p);
    1122          214 :         return ref.has_substitutions ();
    1123              :       }
    1124        81159 :       break;
    1125              : 
    1126        81159 :     case FNDEF:
    1127        81159 :       {
    1128        81159 :         const FnType &fn = *static_cast<const FnType *> (x);
    1129        81159 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (fn);
    1130        81159 :         return ref.has_substitutions ();
    1131              :       }
    1132       104269 :       break;
    1133              : 
    1134       104269 :     case ADT:
    1135       104269 :       {
    1136       104269 :         const ADTType &adt = *static_cast<const ADTType *> (x);
    1137       104269 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (adt);
    1138       104269 :         return ref.has_substitutions ();
    1139              :       }
    1140            0 :       break;
    1141              : 
    1142            0 :     case CLOSURE:
    1143            0 :       {
    1144            0 :         const ClosureType &closure = *static_cast<const ClosureType *> (x);
    1145            0 :         const SubstitutionRef &ref
    1146              :           = static_cast<const SubstitutionRef &> (closure);
    1147            0 :         return ref.has_substitutions ();
    1148              :       }
    1149              :       break;
    1150              :     }
    1151              : 
    1152              :   return false;
    1153              : }
    1154              : 
    1155              : bool
    1156       133563 : BaseType::needs_generic_substitutions () const
    1157              : {
    1158       133563 :   const TyTy::BaseType *x = destructure ();
    1159       133563 :   switch (x->get_kind ())
    1160              :     {
    1161              :     case INFER:
    1162              :     case BOOL:
    1163              :     case CHAR:
    1164              :     case INT:
    1165              :     case UINT:
    1166              :     case FLOAT:
    1167              :     case USIZE:
    1168              :     case ISIZE:
    1169              :     case NEVER:
    1170              :     case STR:
    1171              :     case DYNAMIC:
    1172              :     case ERROR:
    1173              :     case FNPTR:
    1174              :     case ARRAY:
    1175              :     case SLICE:
    1176              :     case POINTER:
    1177              :     case REF:
    1178              :     case TUPLE:
    1179              :     case PARAM:
    1180              :     case PLACEHOLDER:
    1181              :     case CONST:
    1182              :     case OPAQUE:
    1183              :       return false;
    1184              : 
    1185         1315 :     case PROJECTION:
    1186         1315 :       {
    1187         1315 :         const ProjectionType &p = *static_cast<const ProjectionType *> (x);
    1188         1315 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (p);
    1189         1315 :         return ref.needs_substitution ();
    1190              :       }
    1191        16102 :       break;
    1192              : 
    1193        16102 :     case FNDEF:
    1194        16102 :       {
    1195        16102 :         const FnType &fn = *static_cast<const FnType *> (x);
    1196        16102 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (fn);
    1197        16102 :         return ref.needs_substitution ();
    1198              :       }
    1199        28242 :       break;
    1200              : 
    1201        28242 :     case ADT:
    1202        28242 :       {
    1203        28242 :         const ADTType &adt = *static_cast<const ADTType *> (x);
    1204        28242 :         const SubstitutionRef &ref = static_cast<const SubstitutionRef &> (adt);
    1205        28242 :         return ref.needs_substitution ();
    1206              :       }
    1207           53 :       break;
    1208              : 
    1209           53 :     case CLOSURE:
    1210           53 :       {
    1211           53 :         const ClosureType &closure = *static_cast<const ClosureType *> (x);
    1212           53 :         const SubstitutionRef &ref
    1213              :           = static_cast<const SubstitutionRef &> (closure);
    1214           53 :         return ref.needs_substitution ();
    1215              :       }
    1216              :       break;
    1217              :     }
    1218              : 
    1219              :   return false;
    1220              : }
    1221              : 
    1222              : const SubstitutionArgumentMappings &
    1223          275 : BaseType::get_subst_argument_mappings () const
    1224              : {
    1225          501 :   static auto empty = SubstitutionArgumentMappings::empty ();
    1226          275 :   const TyTy::BaseType *x = destructure ();
    1227          275 :   switch (x->get_kind ())
    1228              :     {
    1229            0 :     case PROJECTION:
    1230            0 :       {
    1231            0 :         const auto &p = *static_cast<const ProjectionType *> (x);
    1232            0 :         const auto &ref = static_cast<const SubstitutionRef &> (p);
    1233            0 :         return ref.get_substitution_arguments ();
    1234              :       }
    1235            0 :       break;
    1236              : 
    1237            0 :     case FNDEF:
    1238            0 :       {
    1239            0 :         const auto &fn = *static_cast<const FnType *> (x);
    1240            0 :         const auto &ref = static_cast<const SubstitutionRef &> (fn);
    1241            0 :         return ref.get_substitution_arguments ();
    1242              :       }
    1243          273 :       break;
    1244              : 
    1245          273 :     case ADT:
    1246          273 :       {
    1247          273 :         const auto &adt = *static_cast<const ADTType *> (x);
    1248          273 :         const auto &ref = static_cast<const SubstitutionRef &> (adt);
    1249          273 :         return ref.get_substitution_arguments ();
    1250              :       }
    1251            0 :       break;
    1252              : 
    1253            0 :     case CLOSURE:
    1254            0 :       {
    1255            0 :         const auto &closure = *static_cast<const ClosureType *> (x);
    1256            0 :         const auto &ref = static_cast<const SubstitutionRef &> (closure);
    1257            0 :         return ref.get_substitution_arguments ();
    1258              :       }
    1259              :       break;
    1260              : 
    1261              :     default:
    1262              :       return empty;
    1263              :     }
    1264              : 
    1265              :   return empty;
    1266              : }
    1267              : 
    1268              : // InferType
    1269              : 
    1270        37334 : InferType::InferType (HirId ref, InferTypeKind infer_kind, TypeHint hint,
    1271              :                       location_t locus, std::set<HirId> refs)
    1272        37334 :   : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), locus},
    1273              :               refs),
    1274        74668 :     infer_kind (infer_kind), default_hint (hint)
    1275        37334 : {}
    1276              : 
    1277            0 : InferType::InferType (HirId ref, HirId ty_ref, InferTypeKind infer_kind,
    1278              :                       TypeHint hint, location_t locus, std::set<HirId> refs)
    1279              :   : BaseType (ref, ty_ref, KIND,
    1280            0 :               {Resolver::CanonicalPath::create_empty (), locus}, refs),
    1281            0 :     infer_kind (infer_kind), default_hint (hint)
    1282            0 : {}
    1283              : 
    1284              : InferType::InferTypeKind
    1285        87650 : InferType::get_infer_kind () const
    1286              : {
    1287        87650 :   return infer_kind;
    1288              : }
    1289              : 
    1290              : std::string
    1291           33 : InferType::get_name () const
    1292              : {
    1293           33 :   return as_string ();
    1294              : }
    1295              : 
    1296              : void
    1297            0 : InferType::accept_vis (TyVisitor &vis)
    1298              : {
    1299            0 :   vis.visit (*this);
    1300            0 : }
    1301              : 
    1302              : void
    1303          629 : InferType::accept_vis (TyConstVisitor &vis) const
    1304              : {
    1305          629 :   vis.visit (*this);
    1306          629 : }
    1307              : 
    1308              : std::string
    1309           44 : InferType::as_string () const
    1310              : {
    1311           44 :   switch (infer_kind)
    1312              :     {
    1313            4 :     case GENERAL:
    1314            4 :       return "T?";
    1315           36 :     case INTEGRAL:
    1316           36 :       return "<integer>";
    1317            4 :     case FLOAT:
    1318            4 :       return "<float>";
    1319              :     }
    1320            0 :   return "<infer::error>";
    1321              : }
    1322              : 
    1323              : BaseType *
    1324         4036 : InferType::clone () const
    1325              : {
    1326              :   // clones for inference variables are special in that they _must_ exist within
    1327              :   // the type check context and we must ensure we don't loose the chain
    1328              :   // otherwise we will end up in the missing type annotations case
    1329              :   //
    1330              :   // This means we cannot simply take over the same reference we must generate a
    1331              :   // new ref just like the get_implicit_infer_var code then we can setup the
    1332              :   // chain of references accordingly to ensure we don't loose the ability to
    1333              :   // update the inference variables when we solve the type
    1334              : 
    1335         4036 :   auto &mappings = Analysis::Mappings::get ();
    1336         4036 :   auto context = Resolver::TypeCheckContext::get ();
    1337              : 
    1338         4036 :   InferType *clone
    1339              :     = new InferType (mappings.get_next_hir_id (), get_infer_kind (),
    1340         4036 :                      default_hint, get_ident ().locus, get_combined_refs ());
    1341              : 
    1342         4036 :   context->insert_type (Analysis::NodeMapping (mappings.get_current_crate (),
    1343              :                                                UNKNOWN_NODEID,
    1344              :                                                clone->get_ref (),
    1345         4036 :                                                UNKNOWN_LOCAL_DEFID),
    1346              :                         clone);
    1347         4036 :   mappings.insert_location (clone->get_ref (),
    1348              :                             mappings.lookup_location (get_ref ()));
    1349              : 
    1350              :   // setup the chain to reference this
    1351         4036 :   clone->append_reference (get_ref ());
    1352              : 
    1353         4036 :   return clone;
    1354              : }
    1355              : 
    1356              : bool
    1357         1600 : InferType::default_type (BaseType **type) const
    1358              : {
    1359         1600 :   auto context = Resolver::TypeCheckContext::get ();
    1360         1600 :   bool ok = false;
    1361              : 
    1362              :   // NOTE: Calling this error is misleading.
    1363         1600 :   if (default_hint.kind == TypeKind::ERROR)
    1364              :     {
    1365         1600 :       switch (infer_kind)
    1366              :         {
    1367              :         case GENERAL:
    1368              :           return false;
    1369              : 
    1370         1544 :         case INTEGRAL:
    1371         1544 :           {
    1372         1544 :             ok = context->lookup_builtin ("i32", type);
    1373         1544 :             rust_assert (ok);
    1374              :             return ok;
    1375              :           }
    1376              : 
    1377           48 :         case FLOAT:
    1378           48 :           {
    1379           48 :             ok = context->lookup_builtin ("f64", type);
    1380           48 :             rust_assert (ok);
    1381              :             return ok;
    1382              :           }
    1383              :         }
    1384              :       return false;
    1385              :     }
    1386              : 
    1387            0 :   switch (default_hint.kind)
    1388              :     {
    1389            0 :     case ISIZE:
    1390            0 :       ok = context->lookup_builtin ("isize", type);
    1391            0 :       rust_assert (ok);
    1392              :       return ok;
    1393              : 
    1394            0 :     case USIZE:
    1395            0 :       ok = context->lookup_builtin ("usize", type);
    1396            0 :       rust_assert (ok);
    1397              :       return ok;
    1398              : 
    1399            0 :     case INT:
    1400            0 :       switch (default_hint.szhint)
    1401              :         {
    1402            0 :         case TypeHint::SizeHint::S8:
    1403            0 :           ok = context->lookup_builtin ("i8", type);
    1404            0 :           rust_assert (ok);
    1405              :           return ok;
    1406              : 
    1407            0 :         case TypeHint::SizeHint::S16:
    1408            0 :           ok = context->lookup_builtin ("i16", type);
    1409            0 :           rust_assert (ok);
    1410              :           return ok;
    1411              : 
    1412            0 :         case TypeHint::SizeHint::S32:
    1413            0 :           ok = context->lookup_builtin ("i32", type);
    1414            0 :           rust_assert (ok);
    1415              :           return ok;
    1416              : 
    1417            0 :         case TypeHint::SizeHint::S64:
    1418            0 :           ok = context->lookup_builtin ("i64", type);
    1419            0 :           rust_assert (ok);
    1420              :           return ok;
    1421              : 
    1422            0 :         case TypeHint::SizeHint::S128:
    1423            0 :           ok = context->lookup_builtin ("i128", type);
    1424            0 :           rust_assert (ok);
    1425              :           return ok;
    1426              : 
    1427              :         default:
    1428              :           return false;
    1429              :         }
    1430            0 :       break;
    1431              : 
    1432            0 :     case UINT:
    1433            0 :       switch (default_hint.szhint)
    1434              :         {
    1435            0 :         case TypeHint::SizeHint::S8:
    1436            0 :           ok = context->lookup_builtin ("u8", type);
    1437            0 :           rust_assert (ok);
    1438              :           return ok;
    1439              : 
    1440            0 :         case TypeHint::SizeHint::S16:
    1441            0 :           ok = context->lookup_builtin ("u16", type);
    1442            0 :           rust_assert (ok);
    1443              :           return ok;
    1444              : 
    1445            0 :         case TypeHint::SizeHint::S32:
    1446            0 :           ok = context->lookup_builtin ("u32", type);
    1447            0 :           rust_assert (ok);
    1448              :           return ok;
    1449              : 
    1450            0 :         case TypeHint::SizeHint::S64:
    1451            0 :           ok = context->lookup_builtin ("u64", type);
    1452            0 :           rust_assert (ok);
    1453              :           return ok;
    1454              : 
    1455            0 :         case TypeHint::SizeHint::S128:
    1456            0 :           ok = context->lookup_builtin ("u128", type);
    1457            0 :           rust_assert (ok);
    1458              :           return ok;
    1459              : 
    1460              :         default:
    1461              :           return false;
    1462              :         }
    1463            0 :       break;
    1464              : 
    1465            0 :     case TypeKind::FLOAT:
    1466            0 :       switch (default_hint.szhint)
    1467              :         {
    1468            0 :         case TypeHint::SizeHint::S32:
    1469            0 :           ok = context->lookup_builtin ("f32", type);
    1470            0 :           rust_assert (ok);
    1471              :           return ok;
    1472              : 
    1473            0 :         case TypeHint::SizeHint::S64:
    1474            0 :           ok = context->lookup_builtin ("f64", type);
    1475            0 :           rust_assert (ok);
    1476              :           return ok;
    1477              : 
    1478              :         default:
    1479              :           return false;
    1480              :         }
    1481              :       break;
    1482              : 
    1483              :     default:
    1484              :       return false;
    1485              :     }
    1486              : 
    1487              :   return false;
    1488              : }
    1489              : 
    1490              : void
    1491         6489 : InferType::apply_primitive_type_hint (const BaseType &hint)
    1492              : {
    1493         6489 :   switch (hint.get_kind ())
    1494              :     {
    1495         1516 :     case ISIZE:
    1496         1516 :     case USIZE:
    1497         1516 :       infer_kind = INTEGRAL;
    1498         1516 :       default_hint.kind = hint.get_kind ();
    1499         1516 :       break;
    1500              : 
    1501         3643 :     case INT:
    1502         3643 :       {
    1503         3643 :         infer_kind = INTEGRAL;
    1504         3643 :         default_hint.kind = hint.get_kind ();
    1505         3643 :         default_hint.shint = TypeHint::SignedHint::SIGNED;
    1506         3643 :         switch (hint.as<const IntType> ()->get_int_kind ())
    1507              :           {
    1508          124 :           case IntType::I8:
    1509          124 :             default_hint.szhint = TypeHint::SizeHint::S8;
    1510          124 :             break;
    1511           84 :           case IntType::I16:
    1512           84 :             default_hint.szhint = TypeHint::SizeHint::S16;
    1513           84 :             break;
    1514         3337 :           case IntType::I32:
    1515         3337 :             default_hint.szhint = TypeHint::SizeHint::S32;
    1516         3337 :             break;
    1517           84 :           case IntType::I64:
    1518           84 :             default_hint.szhint = TypeHint::SizeHint::S64;
    1519           84 :             break;
    1520           14 :           case IntType::I128:
    1521           14 :             default_hint.szhint = TypeHint::SizeHint::S128;
    1522           14 :             break;
    1523              :           }
    1524              :       }
    1525              :       break;
    1526              : 
    1527         1202 :     case UINT:
    1528         1202 :       {
    1529         1202 :         infer_kind = INTEGRAL;
    1530         1202 :         default_hint.kind = hint.get_kind ();
    1531         1202 :         default_hint.shint = TypeHint::SignedHint::UNSIGNED;
    1532         1202 :         switch (hint.as<const UintType> ()->get_uint_kind ())
    1533              :           {
    1534          520 :           case UintType::U8:
    1535          520 :             default_hint.szhint = TypeHint::SizeHint::S8;
    1536          520 :             break;
    1537          158 :           case UintType::U16:
    1538          158 :             default_hint.szhint = TypeHint::SizeHint::S16;
    1539          158 :             break;
    1540          317 :           case UintType::U32:
    1541          317 :             default_hint.szhint = TypeHint::SizeHint::S32;
    1542          317 :             break;
    1543          186 :           case UintType::U64:
    1544          186 :             default_hint.szhint = TypeHint::SizeHint::S64;
    1545          186 :             break;
    1546           21 :           case UintType::U128:
    1547           21 :             default_hint.szhint = TypeHint::SizeHint::S128;
    1548           21 :             break;
    1549              :           }
    1550              :       }
    1551              :       break;
    1552              : 
    1553          128 :     case TypeKind::FLOAT:
    1554          128 :       {
    1555          128 :         infer_kind = FLOAT;
    1556          128 :         default_hint.shint = TypeHint::SignedHint::SIGNED;
    1557          128 :         default_hint.kind = hint.get_kind ();
    1558          128 :         switch (hint.as<const FloatType> ()->get_float_kind ())
    1559              :           {
    1560           61 :           case FloatType::F32:
    1561           61 :             default_hint.szhint = TypeHint::SizeHint::S32;
    1562           61 :             break;
    1563              : 
    1564           67 :           case FloatType::F64:
    1565           67 :             default_hint.szhint = TypeHint::SizeHint::S64;
    1566           67 :             break;
    1567              :           }
    1568              :       }
    1569              :       break;
    1570              : 
    1571              :     default:
    1572              :       // TODO bool, char, never??
    1573              :       break;
    1574              :     }
    1575         6489 : }
    1576              : 
    1577              : // ErrorType
    1578              : 
    1579       234502 : ErrorType::ErrorType (HirId ref, std::set<HirId> refs)
    1580              :   : BaseType (ref, ref, KIND,
    1581       234502 :               {Resolver::CanonicalPath::create_empty (), UNDEF_LOCATION}, refs)
    1582       234502 : {}
    1583              : 
    1584            5 : ErrorType::ErrorType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    1585              :   : BaseType (ref, ty_ref, KIND,
    1586            5 :               {Resolver::CanonicalPath::create_empty (), UNDEF_LOCATION}, refs)
    1587            5 : {}
    1588              : 
    1589              : std::string
    1590           11 : ErrorType::get_name () const
    1591              : {
    1592           11 :   return as_string ();
    1593              : }
    1594              : 
    1595              : void
    1596            0 : ErrorType::accept_vis (TyVisitor &vis)
    1597              : {
    1598            0 :   vis.visit (*this);
    1599            0 : }
    1600              : 
    1601              : void
    1602            0 : ErrorType::accept_vis (TyConstVisitor &vis) const
    1603              : {
    1604            0 :   vis.visit (*this);
    1605            0 : }
    1606              : 
    1607              : std::string
    1608           11 : ErrorType::as_string () const
    1609              : {
    1610           11 :   return "<tyty::error>";
    1611              : }
    1612              : 
    1613              : BaseType *
    1614            4 : ErrorType::clone () const
    1615              : {
    1616            4 :   return new ErrorType (get_ref (), get_ty_ref (), get_combined_refs ());
    1617              : }
    1618              : 
    1619              : // Struct Field type
    1620              : 
    1621       162170 : StructFieldType::StructFieldType (HirId ref, std::string name, BaseType *ty,
    1622              :                                   location_t locus)
    1623       162170 :   : ref (ref), name (name), ty (ty), locus (locus)
    1624       162170 : {}
    1625              : 
    1626              : HirId
    1627       161084 : StructFieldType::get_ref () const
    1628              : {
    1629       161084 :   return ref;
    1630              : }
    1631              : 
    1632              : std::string
    1633       383964 : StructFieldType::get_name () const
    1634              : {
    1635       383964 :   return name;
    1636              : }
    1637              : 
    1638              : BaseType *
    1639       736589 : StructFieldType::get_field_type () const
    1640              : {
    1641       736589 :   return ty;
    1642              : }
    1643              : 
    1644              : void
    1645         4075 : StructFieldType::set_field_type (BaseType *fty)
    1646              : {
    1647         4075 :   ty = fty;
    1648         4075 : }
    1649              : 
    1650              : void
    1651            0 : StructFieldType::debug () const
    1652              : {
    1653            0 :   rust_debug ("%s", as_string ().c_str ());
    1654            0 : }
    1655              : 
    1656              : location_t
    1657         2429 : StructFieldType::get_locus () const
    1658              : {
    1659         2429 :   return locus;
    1660              : }
    1661              : 
    1662              : std::string
    1663        15874 : StructFieldType::as_string () const
    1664              : {
    1665        15874 :   return name + ":" + get_field_type ()->debug_str ();
    1666              : }
    1667              : 
    1668              : bool
    1669        46371 : StructFieldType::is_equal (const StructFieldType &other) const
    1670              : {
    1671        46371 :   bool names_eq = get_name () == other.get_name ();
    1672              : 
    1673        46371 :   TyTy::BaseType *o = other.get_field_type ();
    1674        46371 :   if (auto op = o->try_as<ParamType> ())
    1675         4119 :     o = op->resolve ();
    1676              : 
    1677        46371 :   bool types_eq = get_field_type ()->is_equal (*o);
    1678              : 
    1679        46371 :   return names_eq && types_eq;
    1680              : }
    1681              : 
    1682              : StructFieldType *
    1683       154281 : StructFieldType::clone () const
    1684              : {
    1685       154281 :   return new StructFieldType (get_ref (), get_name (),
    1686       308562 :                               get_field_type ()->clone (), locus);
    1687              : }
    1688              : 
    1689              : StructFieldType *
    1690         3216 : StructFieldType::monomorphized_clone () const
    1691              : {
    1692         3216 :   return new StructFieldType (get_ref (), get_name (),
    1693         6432 :                               get_field_type ()->monomorphized_clone (), locus);
    1694              : }
    1695              : 
    1696              : // VariantDef
    1697              : 
    1698              : std::string
    1699            6 : VariantDef::variant_type_string (VariantType type)
    1700              : {
    1701            6 :   switch (type)
    1702              :     {
    1703            0 :     case NUM:
    1704            0 :       return "enumeral";
    1705            4 :     case TUPLE:
    1706            4 :       return "tuple";
    1707            2 :     case STRUCT:
    1708            2 :       return "struct";
    1709            0 :     case UNIT:
    1710            0 :       return "unit struct";
    1711              :     }
    1712            0 :   rust_unreachable ();
    1713              :   return "";
    1714              : }
    1715              : 
    1716         3927 : VariantDef::VariantDef (HirId id, DefId defid, std::string identifier,
    1717              :                         RustIdent ident,
    1718              :                         tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant)
    1719         7854 :   : id (id), defid (defid), identifier (identifier), ident (ident),
    1720         7854 :     discriminant (std::move (discriminant))
    1721              : 
    1722              : {
    1723         3927 :   type = VariantType::NUM;
    1724         3927 :   fields = {};
    1725         3927 : }
    1726              : 
    1727       148744 : VariantDef::VariantDef (HirId id, DefId defid, std::string identifier,
    1728              :                         RustIdent ident, VariantType type,
    1729              :                         tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant,
    1730              :                         std::vector<StructFieldType *> fields)
    1731       297488 :   : id (id), defid (defid), identifier (identifier), ident (ident), type (type),
    1732       297488 :     discriminant (std::move (discriminant)), fields (fields)
    1733              : {
    1734       148744 :   rust_assert ((type == VariantType::NUM && fields.empty ())
    1735              :                || (type == VariantType::UNIT && fields.empty ())
    1736              :                || type == VariantType::TUPLE || type == VariantType::STRUCT);
    1737       148744 : }
    1738              : 
    1739              : VariantDef &
    1740        15018 : VariantDef::get_error_node ()
    1741              : {
    1742        15018 :   static VariantDef node
    1743         3171 :     = VariantDef (UNKNOWN_HIRID, UNKNOWN_DEFID, "",
    1744         3171 :                   {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
    1745        24531 :                   tl::nullopt);
    1746              : 
    1747        15018 :   return node;
    1748              : }
    1749              : 
    1750              : bool
    1751         1899 : VariantDef::is_error () const
    1752              : {
    1753         1899 :   return get_id () == UNKNOWN_HIRID;
    1754              : }
    1755              : 
    1756              : HirId
    1757        18325 : VariantDef::get_id () const
    1758              : {
    1759        18325 :   return id;
    1760              : }
    1761              : 
    1762              : DefId
    1763            0 : VariantDef::get_defid () const
    1764              : {
    1765            0 :   return defid;
    1766              : }
    1767              : 
    1768              : VariantDef::VariantType
    1769       404679 : VariantDef::get_variant_type () const
    1770              : {
    1771       404679 :   return type;
    1772              : }
    1773              : 
    1774              : bool
    1775            0 : VariantDef::is_data_variant () const
    1776              : {
    1777            0 :   return type != VariantType::NUM;
    1778              : }
    1779              : 
    1780              : bool
    1781        14463 : VariantDef::is_dataless_variant () const
    1782              : {
    1783        14463 :   return type == VariantType::NUM;
    1784              : }
    1785              : 
    1786              : std::string
    1787        16899 : VariantDef::get_identifier () const
    1788              : {
    1789        16899 :   return identifier;
    1790              : }
    1791              : 
    1792              : size_t
    1793       515882 : VariantDef::num_fields () const
    1794              : {
    1795       515882 :   return fields.size ();
    1796              : }
    1797              : 
    1798              : StructFieldType *
    1799       166199 : VariantDef::get_field_at_index (size_t index)
    1800              : {
    1801       166199 :   rust_assert (index < fields.size ());
    1802       166199 :   return fields.at (index);
    1803              : }
    1804              : 
    1805              : std::vector<StructFieldType *> &
    1806       170099 : VariantDef::get_fields ()
    1807              : {
    1808       170099 :   return fields;
    1809              : }
    1810              : 
    1811              : bool
    1812        18238 : VariantDef::lookup_field (const std::string &lookup,
    1813              :                           StructFieldType **field_lookup, size_t *index) const
    1814              : {
    1815        18238 :   size_t i = 0;
    1816        89105 :   for (auto &field : fields)
    1817              :     {
    1818        89097 :       if (field->get_name ().compare (lookup) == 0)
    1819              :         {
    1820        18230 :           if (index != nullptr)
    1821        12758 :             *index = i;
    1822              : 
    1823        18230 :           if (field_lookup != nullptr)
    1824        11523 :             *field_lookup = field;
    1825              : 
    1826        18238 :           return true;
    1827              :         }
    1828        70867 :       i++;
    1829              :     }
    1830              :   return false;
    1831              : }
    1832              : 
    1833              : HIR::Expr &
    1834         3778 : VariantDef::get_discriminant ()
    1835              : {
    1836         3778 :   return *discriminant.value ();
    1837              : }
    1838              : 
    1839              : const HIR::Expr &
    1840        68424 : VariantDef::get_discriminant () const
    1841              : {
    1842        68424 :   return *discriminant.value ();
    1843              : }
    1844              : 
    1845              : bool
    1846       148979 : VariantDef::has_discriminant () const
    1847              : {
    1848       148979 :   return discriminant.has_value ();
    1849              : }
    1850              : 
    1851              : std::string
    1852        13908 : VariantDef::as_string () const
    1853              : {
    1854        13908 :   if (type == VariantType::NUM)
    1855         7142 :     return identifier
    1856         7142 :            + (has_discriminant () ? " = " + get_discriminant ().to_string ()
    1857         3571 :                                   : "");
    1858              : 
    1859        10337 :   std::string buffer;
    1860        26211 :   for (size_t i = 0; i < fields.size (); ++i)
    1861              :     {
    1862        31748 :       buffer += fields.at (i)->as_string ();
    1863        15874 :       if ((i + 1) < fields.size ())
    1864         6251 :         buffer += ", ";
    1865              :     }
    1866              : 
    1867        10337 :   if (type == VariantType::TUPLE)
    1868        10522 :     return identifier + " (" + buffer + ")";
    1869              :   else
    1870        10152 :     return identifier + " {" + buffer + "}";
    1871        10337 : }
    1872              : 
    1873              : bool
    1874        53044 : VariantDef::is_equal (const VariantDef &other) const
    1875              : {
    1876        53044 :   if (type != other.type)
    1877              :     return false;
    1878              : 
    1879        52928 :   if (identifier.compare (other.identifier) != 0)
    1880              :     return false;
    1881              : 
    1882        52285 :   if (fields.size () != other.fields.size ())
    1883              :     return false;
    1884              : 
    1885        95210 :   for (size_t i = 0; i < fields.size (); i++)
    1886              :     {
    1887        46371 :       if (!fields.at (i)->is_equal (*other.fields.at (i)))
    1888              :         return false;
    1889              :     }
    1890              : 
    1891              :   return true;
    1892              : }
    1893              : 
    1894              : VariantDef *
    1895       141720 : VariantDef::clone () const
    1896              : {
    1897       141720 :   std::vector<StructFieldType *> cloned_fields;
    1898       296001 :   for (auto &f : fields)
    1899       154281 :     cloned_fields.push_back ((StructFieldType *) f->clone ());
    1900              : 
    1901       141720 :   auto &&discriminant_opt = has_discriminant ()
    1902       141720 :                               ? tl::optional<std::unique_ptr<HIR::Expr>> (
    1903        62432 :                                 get_discriminant ().clone_expr ())
    1904       283440 :                               : tl::nullopt;
    1905              : 
    1906       141720 :   return new VariantDef (id, defid, identifier, ident, type,
    1907       425160 :                          std::move (discriminant_opt), cloned_fields);
    1908       141720 : }
    1909              : 
    1910              : VariantDef *
    1911         3686 : VariantDef::monomorphized_clone () const
    1912              : {
    1913         3686 :   std::vector<StructFieldType *> cloned_fields;
    1914         6902 :   for (auto &f : fields)
    1915         3216 :     cloned_fields.push_back ((StructFieldType *) f->monomorphized_clone ());
    1916              : 
    1917         3686 :   auto discriminant_opt = has_discriminant ()
    1918         3686 :                             ? tl::optional<std::unique_ptr<HIR::Expr>> (
    1919         2421 :                               get_discriminant ().clone_expr ())
    1920         3686 :                             : tl::nullopt;
    1921              : 
    1922         3686 :   return new VariantDef (id, defid, identifier, ident, type,
    1923        11058 :                          std::move (discriminant_opt), cloned_fields);
    1924         3686 : }
    1925              : 
    1926              : const RustIdent &
    1927        33720 : VariantDef::get_ident () const
    1928              : {
    1929        33720 :   return ident;
    1930              : }
    1931              : 
    1932              : // ADTType
    1933              : 
    1934            0 : ADTType::ADTType (DefId id, HirId ref, std::string identifier, RustIdent ident,
    1935              :                   ADTKind adt_kind, std::vector<VariantDef *> variants,
    1936              :                   std::vector<SubstitutionParamMapping> subst_refs,
    1937              :                   SubstitutionArgumentMappings generic_arguments,
    1938              :                   RegionConstraints region_constraints, std::set<HirId> refs)
    1939              :   : BaseType (ref, ref, TypeKind::ADT, ident, refs),
    1940              :     SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
    1941              :                      region_constraints),
    1942            0 :     id (id), identifier (identifier), variants (variants), adt_kind (adt_kind)
    1943            0 : {}
    1944              : 
    1945          105 : ADTType::ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
    1946              :                   RustIdent ident, ADTKind adt_kind,
    1947              :                   std::vector<VariantDef *> variants,
    1948              :                   std::vector<SubstitutionParamMapping> subst_refs,
    1949              :                   SubstitutionArgumentMappings generic_arguments,
    1950              :                   RegionConstraints region_constraints, std::set<HirId> refs)
    1951              :   : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
    1952              :     SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
    1953              :                      region_constraints),
    1954          315 :     id (id), identifier (identifier), variants (variants), adt_kind (adt_kind)
    1955          105 : {}
    1956              : 
    1957       109591 : ADTType::ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
    1958              :                   RustIdent ident, ADTKind adt_kind,
    1959              :                   std::vector<VariantDef *> variants,
    1960              :                   std::vector<SubstitutionParamMapping> subst_refs,
    1961              :                   ReprOptions repr,
    1962              :                   SubstitutionArgumentMappings generic_arguments,
    1963              :                   RegionConstraints region_constraints, std::set<HirId> refs)
    1964              :   : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
    1965              :     SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
    1966              :                      region_constraints),
    1967       109591 :     id (id), identifier (identifier), variants (variants), adt_kind (adt_kind),
    1968       219182 :     repr (repr)
    1969       109591 : {}
    1970              : 
    1971              : void
    1972        11712 : ADTType::accept_vis (TyVisitor &vis)
    1973              : {
    1974        11712 :   vis.visit (*this);
    1975        11712 : }
    1976              : 
    1977              : void
    1978        30994 : ADTType::accept_vis (TyConstVisitor &vis) const
    1979              : {
    1980        30994 :   vis.visit (*this);
    1981        30994 : }
    1982              : 
    1983              : std::string
    1984        10251 : ADTType::as_string () const
    1985              : {
    1986        10251 :   std::string variants_buffer;
    1987        24159 :   for (size_t i = 0; i < number_of_variants (); ++i)
    1988              :     {
    1989        13908 :       TyTy::VariantDef *variant = variants.at (i);
    1990        27816 :       variants_buffer += variant->as_string ();
    1991        13908 :       if ((i + 1) < number_of_variants ())
    1992         3667 :         variants_buffer += ", ";
    1993              :     }
    1994              : 
    1995        30753 :   return identifier + subst_as_string () + "{" + variants_buffer + "}";
    1996        10251 : }
    1997              : 
    1998              : bool
    1999        44100 : ADTType::is_equal (const BaseType &other) const
    2000              : {
    2001        44100 :   if (get_kind () != other.get_kind ())
    2002              :     return false;
    2003              : 
    2004        34631 :   auto other2 = other.as<const ADTType> ();
    2005        34631 :   if (get_adt_kind () != other2->get_adt_kind ())
    2006              :     return false;
    2007              : 
    2008        33902 :   if (number_of_variants () != other2->number_of_variants ())
    2009              :     return false;
    2010              : 
    2011        33902 :   if (has_substitutions_defined () != other2->has_substitutions_defined ())
    2012              :     return false;
    2013              : 
    2014        33646 :   if (has_substitutions_defined ())
    2015              :     {
    2016        11455 :       if (get_num_substitutions () != other2->get_num_substitutions ())
    2017              :         return false;
    2018              : 
    2019        22982 :       for (size_t i = 0; i < get_num_substitutions (); i++)
    2020              :         {
    2021        12140 :           const SubstitutionParamMapping &a = substitutions.at (i);
    2022        12140 :           const SubstitutionParamMapping &b = other2->substitutions.at (i);
    2023              : 
    2024        12140 :           const auto &aa = a.get_param_ty ();
    2025        12140 :           const auto &bb = b.get_param_ty ();
    2026        12140 :           if (!aa->is_equal (*bb))
    2027              :             return false;
    2028              :         }
    2029              :     }
    2030              : 
    2031        81872 :   for (size_t i = 0; i < number_of_variants (); i++)
    2032              :     {
    2033        53044 :       const TyTy::VariantDef *a = get_variants ().at (i);
    2034        53044 :       const TyTy::VariantDef *b = other2->get_variants ().at (i);
    2035              : 
    2036        53044 :       if (!a->is_equal (*b))
    2037              :         return false;
    2038              :     }
    2039              : 
    2040              :   return true;
    2041              : }
    2042              : 
    2043              : bool
    2044            2 : ADTType::is_zero_sized () const
    2045              : {
    2046            2 :   auto phantom = Analysis::Mappings::get ().lookup_lang_item (
    2047              :     LangItem::Kind::PHANTOM_DATA);
    2048            2 :   if (phantom.has_value () && phantom.value () == get_id ())
    2049            1 :     return true;
    2050              : 
    2051            1 :   for (auto *variant : get_variants ())
    2052              :     {
    2053            1 :       for (size_t i = 0; i < variant->num_fields (); i++)
    2054              :         {
    2055            1 :           if (!variant->get_field_at_index (i)
    2056              :                  ->get_field_type ()
    2057            1 :                  ->is_zero_sized ())
    2058            2 :             return false;
    2059              :         }
    2060              :     }
    2061              :   return true;
    2062              : }
    2063              : 
    2064              : DefId
    2065       201024 : ADTType::get_id () const
    2066              : {
    2067       201024 :   return id;
    2068              : }
    2069              : 
    2070              : BaseType *
    2071       104094 : ADTType::clone () const
    2072              : {
    2073       104094 :   std::vector<VariantDef *> cloned_variants;
    2074       243915 :   for (auto &variant : variants)
    2075       139821 :     cloned_variants.push_back (variant->clone ());
    2076              : 
    2077       104094 :   return new ADTType (get_id (), get_ref (), get_ty_ref (), identifier, ident,
    2078       104094 :                       get_adt_kind (), cloned_variants, clone_substs (),
    2079       104094 :                       get_repr_options (), used_arguments,
    2080       312282 :                       get_region_constraints (), get_combined_refs ());
    2081       104094 : }
    2082              : 
    2083              : static bool
    2084        12214 : handle_substitions (SubstitutionArgumentMappings &subst_mappings,
    2085              :                     StructFieldType *field)
    2086              : {
    2087        12214 :   auto fty = field->get_field_type ();
    2088        12214 :   if (auto p = fty->try_as<ParamType> ())
    2089              :     {
    2090         8697 :       SubstitutionArg arg = SubstitutionArg::error ();
    2091         8697 :       bool ok = subst_mappings.get_argument_for_symbol (p, &arg);
    2092         8697 :       if (ok)
    2093              :         {
    2094         8660 :           auto argt = arg.get_tyty ();
    2095         8660 :           bool arg_is_param = argt->get_kind () == TyTy::TypeKind::PARAM;
    2096         8660 :           bool arg_is_concrete = argt->get_kind () != TyTy::TypeKind::INFER;
    2097              : 
    2098         8660 :           if (arg_is_param || arg_is_concrete)
    2099              :             {
    2100         2766 :               auto new_field = argt->clone ();
    2101         2766 :               new_field->set_ref (fty->get_ref ());
    2102         2766 :               field->set_field_type (new_field);
    2103              :             }
    2104              :           else
    2105              :             {
    2106         5894 :               field->get_field_type ()->set_ty_ref (argt->get_ref ());
    2107              :             }
    2108              :         }
    2109              :     }
    2110         3517 :   else if (fty->has_substitutions_defined () || !fty->is_concrete ())
    2111              :     {
    2112         1309 :       BaseType *concrete
    2113         1309 :         = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings);
    2114              : 
    2115         1309 :       if (concrete->get_kind () == TyTy::TypeKind::ERROR)
    2116              :         {
    2117            0 :           rust_error_at (subst_mappings.get_locus (),
    2118              :                          "Failed to resolve field substitution type: %s",
    2119            0 :                          fty->as_string ().c_str ());
    2120            0 :           return false;
    2121              :         }
    2122              : 
    2123         1309 :       auto new_field = concrete->clone ();
    2124         1309 :       new_field->set_ref (fty->get_ref ());
    2125         1309 :       field->set_field_type (new_field);
    2126              :     }
    2127              : 
    2128              :   return true;
    2129              : }
    2130              : 
    2131              : ADTType *
    2132         9287 : ADTType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
    2133              : {
    2134         9287 :   auto adt = clone ()->as<ADTType> ();
    2135         9287 :   adt->set_ty_ref (mappings.get_next_hir_id ());
    2136         9287 :   adt->used_arguments = subst_mappings;
    2137              : 
    2138        19443 :   for (auto &sub : adt->get_substs ())
    2139              :     {
    2140        10156 :       SubstitutionArg arg = SubstitutionArg::error ();
    2141        10156 :       bool ok
    2142        10156 :         = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg);
    2143        10156 :       if (ok)
    2144        10099 :         sub.fill_param_ty (subst_mappings, subst_mappings.get_locus ());
    2145              :     }
    2146              : 
    2147        23750 :   for (auto &variant : adt->get_variants ())
    2148              :     {
    2149        14463 :       if (variant->is_dataless_variant ())
    2150         4609 :         continue;
    2151              : 
    2152        22068 :       for (auto &field : variant->get_fields ())
    2153              :         {
    2154        12214 :           bool ok = ::Rust::TyTy::handle_substitions (subst_mappings, field);
    2155        12214 :           if (!ok)
    2156         9287 :             return adt;
    2157              :         }
    2158              :     }
    2159              : 
    2160              :   return adt;
    2161              : }
    2162              : 
    2163              : bool
    2164         3009 : ADTType::contains_unsafe_cell () const
    2165              : {
    2166         3009 :   if (auto unsafe_cell
    2167         3009 :       = mappings.lookup_lang_item (LangItem::Kind::UNSAFE_CELL))
    2168              :     {
    2169            2 :       if (get_id () == *unsafe_cell)
    2170            2 :         return true;
    2171              : 
    2172            0 :       for (auto &variant : get_variants ())
    2173            0 :         for (auto &field : variant->get_fields ())
    2174            0 :           if (field->get_field_type ()->contains_unsafe_cell ())
    2175            2 :             return true;
    2176              :     }
    2177         3007 :   return false;
    2178              : }
    2179              : 
    2180              : bool
    2181         7853 : ADTType::is_unsized () const
    2182              : {
    2183        14905 :   if (is_enum () || is_union () || number_of_variants () == 0)
    2184              :     return false;
    2185              : 
    2186         7046 :   auto &variant = get_variants ().front ();
    2187         7046 :   if (variant->num_fields () == 0)
    2188              :     return false;
    2189              : 
    2190         5570 :   const TyTy::BaseType *last_field_type
    2191         5570 :     = variant->get_field_at_index (variant->num_fields () - 1)
    2192         5570 :         ->get_field_type ();
    2193              : 
    2194         5570 :   return last_field_type->is_unsized ();
    2195              : }
    2196              : 
    2197              : bool
    2198            0 : ADTType::is_box () const
    2199              : {
    2200            0 :   if (auto owned_box = mappings.lookup_lang_item (LangItem::Kind::OWNED_BOX))
    2201            0 :     if (get_id () == owned_box)
    2202            0 :       return true;
    2203            0 :   return false;
    2204              : }
    2205              : 
    2206              : // TupleType
    2207              : 
    2208         6528 : TupleType::TupleType (HirId ref, location_t locus, std::vector<TyVar> fields,
    2209              :                       std::set<HirId> refs)
    2210         6528 :   : BaseType (ref, ref, KIND, {Resolver::CanonicalPath::create_empty (), locus},
    2211              :               refs),
    2212        13056 :     fields (fields)
    2213         6528 : {}
    2214              : 
    2215         8052 : TupleType::TupleType (HirId ref, HirId ty_ref, location_t locus,
    2216              :                       std::vector<TyVar> fields, std::set<HirId> refs)
    2217              :   : BaseType (ref, ty_ref, KIND,
    2218         8052 :               {Resolver::CanonicalPath::create_empty (), locus}, refs),
    2219        16104 :     fields (fields)
    2220         8052 : {}
    2221              : 
    2222              : TupleType *
    2223        34752 : TupleType::get_unit_type ()
    2224              : {
    2225        34752 :   static TupleType *ret = nullptr;
    2226        34752 :   if (ret == nullptr)
    2227         9942 :     ret = new TupleType (Analysis::Mappings::get ().get_next_hir_id (),
    2228         9942 :                          BUILTINS_LOCATION);
    2229        34752 :   return ret;
    2230              : }
    2231              : 
    2232              : size_t
    2233       165677 : TupleType::num_fields () const
    2234              : {
    2235       165677 :   return fields.size ();
    2236              : }
    2237              : 
    2238              : const std::vector<TyVar> &
    2239        20677 : TupleType::get_fields () const
    2240              : {
    2241        20677 :   return fields;
    2242              : }
    2243              : 
    2244              : void
    2245          600 : TupleType::accept_vis (TyVisitor &vis)
    2246              : {
    2247          600 :   vis.visit (*this);
    2248          600 : }
    2249              : 
    2250              : void
    2251        18654 : TupleType::accept_vis (TyConstVisitor &vis) const
    2252              : {
    2253        18654 :   vis.visit (*this);
    2254        18654 : }
    2255              : 
    2256              : std::string
    2257         9059 : TupleType::as_string () const
    2258              : {
    2259         9059 :   size_t i = 0;
    2260         9059 :   std::string fields_buffer;
    2261        11364 :   for (const TyVar &field : get_fields ())
    2262              :     {
    2263         4610 :       fields_buffer += field.get_tyty ()->as_string ();
    2264         2305 :       bool has_next = (i + 1) < get_fields ().size ();
    2265         2305 :       fields_buffer += has_next ? ", " : "";
    2266         2305 :       i++;
    2267              :     }
    2268        18118 :   return "(" + fields_buffer + ")";
    2269         9059 : }
    2270              : 
    2271              : std::string
    2272         2558 : TupleType::get_name () const
    2273              : {
    2274         2558 :   size_t i = 0;
    2275         2558 :   std::string fields_buffer;
    2276         7519 :   for (const TyVar &field : get_fields ())
    2277              :     {
    2278         9922 :       fields_buffer += field.get_tyty ()->get_name ();
    2279         4961 :       bool has_next = (i + 1) < get_fields ().size ();
    2280         4961 :       fields_buffer += has_next ? ", " : "";
    2281         4961 :       i++;
    2282              :     }
    2283         5116 :   return "(" + fields_buffer + ")";
    2284         2558 : }
    2285              : 
    2286              : BaseType *
    2287        19614 : TupleType::get_field (size_t index) const
    2288              : {
    2289        19614 :   return fields.at (index).get_tyty ();
    2290              : }
    2291              : 
    2292              : bool
    2293        15491 : TupleType::is_equal (const BaseType &other) const
    2294              : {
    2295        15491 :   if (get_kind () != other.get_kind ())
    2296              :     return false;
    2297              : 
    2298        15442 :   auto other2 = other.as<const TupleType> ();
    2299        15442 :   if (num_fields () != other2->num_fields ())
    2300              :     return false;
    2301              : 
    2302        17760 :   for (size_t i = 0; i < num_fields (); i++)
    2303              :     {
    2304         2509 :       if (!get_field (i)->is_equal (*other2->get_field (i)))
    2305              :         return false;
    2306              :     }
    2307              :   return true;
    2308              : }
    2309              : 
    2310              : bool
    2311            1 : TupleType::is_zero_sized () const
    2312              : {
    2313            1 :   if (num_fields () == 0)
    2314              :     return true;
    2315            0 :   for (size_t i = 0; i < num_fields (); i++)
    2316              :     {
    2317            0 :       if (!get_field (i)->is_zero_sized ())
    2318              :         return false;
    2319              :     }
    2320              :   return true;
    2321              : }
    2322              : 
    2323              : BaseType *
    2324         7523 : TupleType::clone () const
    2325              : {
    2326         7523 :   std::vector<TyVar> cloned_fields;
    2327        14263 :   for (const auto &f : fields)
    2328         6740 :     cloned_fields.push_back (f.clone ());
    2329              : 
    2330         7523 :   return new TupleType (get_ref (), get_ty_ref (), get_ident ().locus,
    2331        15046 :                         cloned_fields, get_combined_refs ());
    2332         7523 : }
    2333              : 
    2334              : TupleType *
    2335          305 : TupleType::handle_substitions (SubstitutionArgumentMappings &mappings)
    2336              : {
    2337          305 :   auto &mappings_table = Analysis::Mappings::get ();
    2338              : 
    2339          305 :   auto tuple = clone ()->as<TupleType> ();
    2340          305 :   tuple->set_ref (mappings_table.get_next_hir_id ());
    2341          305 :   tuple->set_ty_ref (mappings_table.get_next_hir_id ());
    2342              : 
    2343         1195 :   for (size_t i = 0; i < tuple->fields.size (); i++)
    2344              :     {
    2345          585 :       TyVar &field = fields.at (i);
    2346          585 :       if (!field.get_tyty ()->is_concrete ())
    2347              :         {
    2348          358 :           BaseType *concrete
    2349          358 :             = Resolver::SubstMapperInternal::Resolve (field.get_tyty (),
    2350              :                                                       mappings);
    2351          358 :           tuple->fields[i]
    2352          358 :             = TyVar::subst_covariant_var (field.get_tyty (), concrete);
    2353              :         }
    2354              :     }
    2355              : 
    2356          305 :   return tuple;
    2357              : }
    2358              : 
    2359              : bool
    2360           21 : TupleType::contains_unsafe_cell () const
    2361              : {
    2362           21 :   for (auto &field : get_fields ())
    2363            0 :     if (field.get_tyty ()->contains_unsafe_cell ())
    2364           21 :       return true;
    2365              :   return false;
    2366              : }
    2367              : 
    2368              : void
    2369        25028 : FnType::accept_vis (TyVisitor &vis)
    2370              : {
    2371        25028 :   vis.visit (*this);
    2372        25028 : }
    2373              : 
    2374              : void
    2375        19006 : FnType::accept_vis (TyConstVisitor &vis) const
    2376              : {
    2377        19006 :   vis.visit (*this);
    2378        19006 : }
    2379              : 
    2380              : std::string
    2381        34928 : FnType::as_string () const
    2382              : {
    2383        34928 :   std::string params_str = "";
    2384        77115 :   for (auto &param : params)
    2385              :     {
    2386        42187 :       auto &pattern = param.get_pattern ();
    2387        42187 :       auto ty = param.get_type ();
    2388       126561 :       params_str += pattern.to_string () + " " + ty->as_string ();
    2389        42187 :       params_str += ",";
    2390              :     }
    2391              : 
    2392        34928 :   std::string ret_str = type->as_string ();
    2393       104784 :   return "fn" + subst_as_string () + " (" + params_str + ") -> " + ret_str;
    2394        34928 : }
    2395              : 
    2396              : bool
    2397         9579 : FnType::is_equal (const BaseType &other) const
    2398              : {
    2399         9579 :   if (get_kind () != other.get_kind ())
    2400              :     return false;
    2401              : 
    2402         9579 :   auto &other2 = static_cast<const FnType &> (other);
    2403        28737 :   if (get_identifier ().compare (other2.get_identifier ()) != 0)
    2404              :     return false;
    2405              : 
    2406         9579 :   if (!get_return_type ()->is_equal (*other2.get_return_type ()))
    2407              :     return false;
    2408              : 
    2409         7763 :   if (has_substitutions_defined () != other2.has_substitutions_defined ())
    2410              :     return false;
    2411              : 
    2412         4620 :   if (has_substitutions_defined ())
    2413              :     {
    2414          708 :       if (get_num_substitutions () != other2.get_num_substitutions ())
    2415              :         return false;
    2416              : 
    2417              :       const FnType &ofn = static_cast<const FnType &> (other);
    2418         1045 :       for (size_t i = 0; i < get_num_substitutions (); i++)
    2419              :         {
    2420          678 :           const SubstitutionParamMapping &a = get_substs ().at (i);
    2421          678 :           const SubstitutionParamMapping &b = ofn.get_substs ().at (i);
    2422              : 
    2423          678 :           const auto *pa = a.get_param_ty ();
    2424          678 :           const auto *pb = b.get_param_ty ();
    2425          678 :           if (!pa->is_equal (*pb))
    2426              :             return false;
    2427              :         }
    2428              :     }
    2429              : 
    2430         4279 :   if (num_params () != other2.num_params ())
    2431              :     return false;
    2432              : 
    2433        11343 :   for (size_t i = 0; i < num_params (); i++)
    2434              :     {
    2435         7066 :       auto lhs = param_at (i).get_type ();
    2436         7066 :       auto rhs = other2.param_at (i).get_type ();
    2437         7066 :       if (!lhs->is_equal (*rhs))
    2438              :         return false;
    2439              :     }
    2440              :   return true;
    2441              : }
    2442              : 
    2443              : BaseType *
    2444        15136 : FnType::clone () const
    2445              : {
    2446        15136 :   std::vector<TyTy::FnParam> cloned_params;
    2447        37480 :   for (auto &p : params)
    2448        22344 :     cloned_params.push_back (p.clone ());
    2449              : 
    2450        30272 :   return new FnType (get_ref (), get_ty_ref (), get_id (), get_identifier (),
    2451        15136 :                      ident, flags, abi, std::move (cloned_params),
    2452        15136 :                      get_return_type ()->clone (), clone_substs (),
    2453              :                      get_substitution_arguments (), get_region_constraints (),
    2454        75680 :                      get_combined_refs ());
    2455        15136 : }
    2456              : 
    2457              : FnType *
    2458        13629 : FnType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
    2459              : {
    2460        13629 :   FnType *fn = static_cast<FnType *> (clone ());
    2461        13629 :   fn->set_ty_ref (mappings.get_next_hir_id ());
    2462        13629 :   fn->used_arguments = subst_mappings;
    2463              : 
    2464        31979 :   for (auto &sub : fn->get_substs ())
    2465              :     {
    2466        18350 :       SubstitutionArg arg = SubstitutionArg::error ();
    2467              : 
    2468        18350 :       bool ok
    2469        18350 :         = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg);
    2470        18350 :       if (ok)
    2471              :         {
    2472        17870 :           sub.fill_param_ty (subst_mappings, subst_mappings.get_locus ());
    2473              :         }
    2474              :     }
    2475              : 
    2476        13629 :   auto fty = fn->get_return_type ();
    2477        13629 :   bool is_param_ty = fty->get_kind () == TypeKind::PARAM;
    2478        13629 :   if (is_param_ty)
    2479              :     {
    2480         4055 :       ParamType *p = static_cast<ParamType *> (fty);
    2481              : 
    2482         4055 :       SubstitutionArg arg = SubstitutionArg::error ();
    2483         4055 :       bool ok = subst_mappings.get_argument_for_symbol (p, &arg);
    2484         4055 :       if (ok)
    2485              :         {
    2486         4048 :           auto argt = arg.get_tyty ();
    2487         4048 :           bool arg_is_param = argt->get_kind () == TyTy::TypeKind::PARAM;
    2488         4048 :           bool arg_is_concrete = argt->get_kind () != TyTy::TypeKind::INFER;
    2489              : 
    2490         4048 :           if (arg_is_param || arg_is_concrete)
    2491              :             {
    2492         1589 :               auto new_field = argt->clone ();
    2493         1589 :               new_field->set_ref (fty->get_ref ());
    2494         1589 :               fn->type = new_field;
    2495              :             }
    2496              :           else
    2497              :             {
    2498         2459 :               fty->set_ty_ref (argt->get_ref ());
    2499              :             }
    2500              :         }
    2501              :     }
    2502         9574 :   else if (fty->needs_generic_substitutions () || !fty->is_concrete ())
    2503              :     {
    2504         3637 :       BaseType *concrete
    2505         3637 :         = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings);
    2506              : 
    2507         3637 :       if (concrete == nullptr || concrete->get_kind () == TyTy::TypeKind::ERROR)
    2508              :         {
    2509            0 :           rust_error_at (subst_mappings.get_locus (),
    2510              :                          "Failed to resolve field substitution type: %s",
    2511            0 :                          fty->as_string ().c_str ());
    2512            0 :           return nullptr;
    2513              :         }
    2514              : 
    2515         3637 :       auto new_field = concrete->clone ();
    2516         3637 :       new_field->set_ref (fty->get_ref ());
    2517         3637 :       fn->type = new_field;
    2518              :     }
    2519              : 
    2520        33669 :   for (auto &param : fn->get_params ())
    2521              :     {
    2522        20040 :       auto fty = param.get_type ();
    2523              : 
    2524        20040 :       bool is_param_ty = fty->get_kind () == TypeKind::PARAM;
    2525        20040 :       if (is_param_ty)
    2526              :         {
    2527         6819 :           ParamType *p = static_cast<ParamType *> (fty);
    2528              : 
    2529         6819 :           SubstitutionArg arg = SubstitutionArg::error ();
    2530         6819 :           bool ok = subst_mappings.get_argument_for_symbol (p, &arg);
    2531         6819 :           if (ok)
    2532              :             {
    2533         6761 :               auto argt = arg.get_tyty ();
    2534         6761 :               bool arg_is_param = argt->get_kind () == TyTy::TypeKind::PARAM;
    2535         6761 :               bool arg_is_concrete = argt->get_kind () != TyTy::TypeKind::INFER;
    2536              : 
    2537         6761 :               if (arg_is_param || arg_is_concrete)
    2538              :                 {
    2539         2541 :                   auto new_field = argt->clone ();
    2540         2541 :                   new_field->set_ref (fty->get_ref ());
    2541         2541 :                   param.set_type (new_field);
    2542              :                 }
    2543              :               else
    2544              :                 {
    2545         4220 :                   fty->set_ty_ref (argt->get_ref ());
    2546              :                 }
    2547              :             }
    2548              :         }
    2549        13221 :       else if (fty->has_substitutions_defined () || !fty->is_concrete ())
    2550              :         {
    2551        11952 :           BaseType *concrete
    2552        11952 :             = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings);
    2553              : 
    2554        11952 :           if (concrete == nullptr
    2555        11952 :               || concrete->get_kind () == TyTy::TypeKind::ERROR)
    2556              :             {
    2557            0 :               rust_error_at (subst_mappings.get_locus (),
    2558              :                              "Failed to resolve field substitution type: %s",
    2559            0 :                              fty->as_string ().c_str ());
    2560            0 :               return nullptr;
    2561              :             }
    2562              : 
    2563        11952 :           auto new_field = concrete->clone ();
    2564        11952 :           new_field->set_ref (fty->get_ref ());
    2565        11952 :           param.set_type (new_field);
    2566              :         }
    2567              :     }
    2568              : 
    2569              :   return fn;
    2570              : }
    2571              : 
    2572              : void
    2573           48 : FnPtr::accept_vis (TyVisitor &vis)
    2574              : {
    2575           48 :   vis.visit (*this);
    2576           48 : }
    2577              : 
    2578              : void
    2579          237 : FnPtr::accept_vis (TyConstVisitor &vis) const
    2580              : {
    2581          237 :   vis.visit (*this);
    2582          237 : }
    2583              : 
    2584              : std::string
    2585           70 : FnPtr::as_string () const
    2586              : {
    2587           70 :   std::string params_str;
    2588              : 
    2589           70 :   auto &params = get_params ();
    2590          122 :   for (auto &p : params)
    2591              :     {
    2592          156 :       params_str += p.get_tyty ()->as_string () + " ,";
    2593              :     }
    2594              : 
    2595           70 :   std::string unsafety = "";
    2596           70 :   if (get_unsafety () == Unsafety::Unsafe)
    2597            0 :     unsafety = "unsafe ";
    2598              : 
    2599           70 :   std::string abi = get_string_from_abi (get_abi ());
    2600          280 :   return unsafety + "abi:" + abi + " " + "fnptr (" + params_str + ") -> "
    2601          210 :          + get_return_type ()->as_string ();
    2602           70 : }
    2603              : 
    2604              : bool
    2605          584 : FnPtr::is_equal (const BaseType &other) const
    2606              : {
    2607          584 :   if (get_kind () != other.get_kind ())
    2608              :     return false;
    2609              : 
    2610          123 :   auto other2 = static_cast<const FnPtr &> (other);
    2611          123 :   auto this_ret_type = get_return_type ();
    2612          123 :   auto other_ret_type = other2.get_return_type ();
    2613          123 :   if (this_ret_type->is_equal (*other_ret_type))
    2614              :     return false;
    2615              : 
    2616           22 :   if (num_params () != other2.num_params ())
    2617              :     return false;
    2618              : 
    2619           22 :   for (size_t i = 0; i < num_params (); i++)
    2620              :     {
    2621            0 :       if (!get_param_type_at (i)->is_equal (*other2.get_param_type_at (i)))
    2622              :         return false;
    2623              :     }
    2624              :   return true;
    2625          123 : }
    2626              : 
    2627              : BaseType *
    2628          975 : FnPtr::clone () const
    2629              : {
    2630          975 :   std::vector<TyVar> cloned_params;
    2631          975 :   cloned_params.reserve (params.size ());
    2632              : 
    2633         1046 :   for (auto &p : params)
    2634           71 :     cloned_params.emplace_back (p.get_ref ());
    2635              : 
    2636          975 :   return new FnPtr (get_ref (), get_ty_ref (), ident.locus,
    2637              :                     std::move (cloned_params), result_type, get_abi (),
    2638          975 :                     get_unsafety (), get_combined_refs ());
    2639          975 : }
    2640              : 
    2641              : FnPtr *
    2642            9 : FnPtr::handle_substitions (SubstitutionArgumentMappings &mappings)
    2643              : {
    2644            9 :   auto &mappings_table = Analysis::Mappings::get ();
    2645              : 
    2646            9 :   auto fn = clone ()->as<FnPtr> ();
    2647            9 :   fn->set_ref (mappings_table.get_next_hir_id ());
    2648            9 :   fn->set_ty_ref (mappings_table.get_next_hir_id ());
    2649              : 
    2650            9 :   if (!fn->result_type.get_tyty ()->is_concrete ())
    2651              :     {
    2652            4 :       BaseType *concrete
    2653            4 :         = Resolver::SubstMapperInternal::Resolve (fn->result_type.get_tyty (),
    2654              :                                                   mappings);
    2655            4 :       fn->result_type
    2656            4 :         = TyVar::subst_covariant_var (fn->result_type.get_tyty (), concrete);
    2657              :     }
    2658              : 
    2659           18 :   for (size_t i = 0; i < fn->params.size (); i++)
    2660              :     {
    2661            9 :       TyVar &field = fn->params.at (i);
    2662            9 :       if (!field.get_tyty ()->is_concrete ())
    2663              :         {
    2664            5 :           BaseType *concrete
    2665            5 :             = Resolver::SubstMapperInternal::Resolve (field.get_tyty (),
    2666              :                                                       mappings);
    2667            5 :           fn->params[i]
    2668            5 :             = TyVar::subst_covariant_var (field.get_tyty (), concrete);
    2669              :         }
    2670              :     }
    2671              : 
    2672            9 :   return fn;
    2673              : }
    2674              : 
    2675              : void
    2676            0 : ClosureType::accept_vis (TyVisitor &vis)
    2677              : {
    2678            0 :   vis.visit (*this);
    2679            0 : }
    2680              : 
    2681              : void
    2682          243 : ClosureType::accept_vis (TyConstVisitor &vis) const
    2683              : {
    2684          243 :   vis.visit (*this);
    2685          243 : }
    2686              : 
    2687              : std::string
    2688          176 : ClosureType::as_string () const
    2689              : {
    2690          176 :   std::string params_buf = parameters->as_string ();
    2691          528 :   return "|" + params_buf + "| {" + result_type.get_tyty ()->as_string () + "}";
    2692          176 : }
    2693              : 
    2694              : bool
    2695          161 : ClosureType::is_equal (const BaseType &other) const
    2696              : {
    2697          161 :   if (other.get_kind () != TypeKind::CLOSURE)
    2698              :     return false;
    2699              : 
    2700          161 :   const ClosureType &other2 = static_cast<const ClosureType &> (other);
    2701          161 :   if (get_def_id () != other2.get_def_id ())
    2702              :     return false;
    2703              : 
    2704          161 :   if (!get_parameters ().is_equal (other2.get_parameters ()))
    2705              :     return false;
    2706              : 
    2707          161 :   return get_result_type ().is_equal (other2.get_result_type ());
    2708              : }
    2709              : 
    2710              : BaseType *
    2711          657 : ClosureType::clone () const
    2712              : {
    2713          657 :   return new ClosureType (get_ref (), get_ty_ref (), ident, id,
    2714          657 :                           (TyTy::TupleType *) parameters->clone (), result_type,
    2715         1314 :                           clone_substs (), captures, get_combined_refs (),
    2716         2628 :                           specified_bounds);
    2717              : }
    2718              : 
    2719              : ClosureType *
    2720            0 : ClosureType::handle_substitions (SubstitutionArgumentMappings &mappings)
    2721              : {
    2722            0 :   rust_unreachable ();
    2723              :   return nullptr;
    2724              : }
    2725              : 
    2726              : void
    2727          119 : ArrayType::accept_vis (TyVisitor &vis)
    2728              : {
    2729          119 :   vis.visit (*this);
    2730          119 : }
    2731              : 
    2732              : void
    2733         4598 : ArrayType::accept_vis (TyConstVisitor &vis) const
    2734              : {
    2735         4598 :   vis.visit (*this);
    2736         4598 : }
    2737              : 
    2738              : std::string
    2739         2434 : ArrayType::as_string () const
    2740              : {
    2741         2434 :   auto cap = get_capacity ();
    2742         2434 :   std::string capacity_str = cap->as_string ();
    2743              : 
    2744         7302 :   return "[" + get_element_type ()->as_string () + "; " + capacity_str + "]";
    2745         2434 : }
    2746              : 
    2747              : bool
    2748         2727 : ArrayType::is_equal (const BaseType &other) const
    2749              : {
    2750         2727 :   if (get_kind () != other.get_kind ())
    2751              :     return false;
    2752              : 
    2753         2666 :   auto other2 = static_cast<const ArrayType &> (other);
    2754              : 
    2755         2666 :   auto this_element_type = get_element_type ();
    2756         2666 :   auto other_element_type = other2.get_element_type ();
    2757              : 
    2758         2666 :   return this_element_type->is_equal (*other_element_type);
    2759         2666 : }
    2760              : 
    2761              : bool
    2762            2 : ArrayType::is_zero_sized () const
    2763              : {
    2764            2 :   if (element_type.get_tyty ()->is_zero_sized ())
    2765              :     return true;
    2766              : 
    2767            1 :   auto *capacity_ty = get_capacity ();
    2768            1 :   if (capacity_ty != nullptr
    2769            1 :       && capacity_ty->get_kind () == TyTy::TypeKind::CONST)
    2770              :     {
    2771            1 :       auto *capacity_const = capacity_ty->as_const_type ();
    2772            1 :       auto &capacity_value
    2773            1 :         = *static_cast<TyTy::ConstValueType *> (capacity_const);
    2774            1 :       auto cap_tree = capacity_value.get_value ();
    2775            1 :       size_t cap_wi = (size_t) wi::to_wide (cap_tree).to_uhwi ();
    2776            1 :       if (cap_wi == 0)
    2777              :         {
    2778            1 :           return true;
    2779              :         }
    2780              :     }
    2781              :   return false;
    2782              : }
    2783              : 
    2784              : BaseType *
    2785        21661 : ArrayType::get_element_type () const
    2786              : {
    2787        21661 :   return element_type.get_tyty ();
    2788              : }
    2789              : 
    2790              : const TyVar &
    2791          270 : ArrayType::get_var_element_type () const
    2792              : {
    2793          270 :   return element_type;
    2794              : }
    2795              : 
    2796              : BaseType *
    2797        15181 : ArrayType::get_capacity () const
    2798              : {
    2799        15181 :   return capacity.get_tyty ();
    2800              : }
    2801              : 
    2802              : BaseType *
    2803          793 : ArrayType::clone () const
    2804              : {
    2805         1586 :   return new ArrayType (get_ref (), get_ty_ref (), ident.locus, capacity,
    2806          793 :                         element_type, get_combined_refs ());
    2807              : }
    2808              : 
    2809              : ArrayType *
    2810           63 : ArrayType::handle_substitions (SubstitutionArgumentMappings &mappings)
    2811              : {
    2812           63 :   auto &mappings_table = Analysis::Mappings::get ();
    2813              : 
    2814           63 :   ArrayType *ref = static_cast<ArrayType *> (clone ());
    2815           63 :   ref->set_ty_ref (mappings_table.get_next_hir_id ());
    2816              : 
    2817              :   // might be &T or &ADT so this needs to be recursive
    2818           63 :   auto base = ref->get_element_type ();
    2819           63 :   BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings);
    2820           63 :   ref->element_type = TyVar::subst_covariant_var (base, concrete);
    2821              : 
    2822              :   // handle capacity type
    2823           63 :   auto cap = ref->get_capacity ();
    2824           63 :   BaseType *concrete_cap
    2825           63 :     = Resolver::SubstMapperInternal::Resolve (cap, mappings);
    2826           63 :   rust_assert (concrete_cap->get_kind () == TyTy::TypeKind::CONST);
    2827           63 :   ref->capacity = TyVar::subst_covariant_var (cap, concrete_cap);
    2828              : 
    2829           63 :   return ref;
    2830              : }
    2831              : 
    2832              : bool
    2833          128 : ArrayType::contains_unsafe_cell () const
    2834              : {
    2835          128 :   return get_element_type ()->contains_unsafe_cell ();
    2836              : }
    2837              : 
    2838              : void
    2839         1952 : SliceType::accept_vis (TyVisitor &vis)
    2840              : {
    2841         1952 :   vis.visit (*this);
    2842         1952 : }
    2843              : 
    2844              : void
    2845          683 : SliceType::accept_vis (TyConstVisitor &vis) const
    2846              : {
    2847          683 :   vis.visit (*this);
    2848          683 : }
    2849              : 
    2850              : std::string
    2851         1096 : SliceType::as_string () const
    2852              : {
    2853         2192 :   return "[" + get_element_type ()->as_string () + "]";
    2854              : }
    2855              : 
    2856              : bool
    2857         4734 : SliceType::is_equal (const BaseType &other) const
    2858              : {
    2859         4734 :   if (get_kind () != other.get_kind ())
    2860              :     return false;
    2861              : 
    2862         3778 :   auto other2 = static_cast<const SliceType &> (other);
    2863              : 
    2864         3778 :   auto this_element_type = get_element_type ();
    2865         3778 :   auto other_element_type = other2.get_element_type ();
    2866              : 
    2867         3778 :   return this_element_type->is_equal (*other_element_type);
    2868         3778 : }
    2869              : 
    2870              : BaseType *
    2871        30533 : SliceType::get_element_type () const
    2872              : {
    2873        30533 :   return element_type.get_tyty ();
    2874              : }
    2875              : 
    2876              : const TyVar &
    2877          136 : SliceType::get_var_element_type () const
    2878              : {
    2879          136 :   return element_type;
    2880              : }
    2881              : 
    2882              : BaseType *
    2883        33200 : SliceType::clone () const
    2884              : {
    2885        66400 :   return new SliceType (get_ref (), get_ty_ref (), ident.locus,
    2886        33200 :                         element_type.clone (), get_combined_refs ());
    2887              : }
    2888              : 
    2889              : SliceType *
    2890         1647 : SliceType::handle_substitions (SubstitutionArgumentMappings &mappings)
    2891              : {
    2892         1647 :   auto &mappings_table = Analysis::Mappings::get ();
    2893              : 
    2894         1647 :   SliceType *ref = static_cast<SliceType *> (clone ());
    2895         1647 :   ref->set_ty_ref (mappings_table.get_next_hir_id ());
    2896              : 
    2897              :   // might be &T or &ADT so this needs to be recursive
    2898         1647 :   auto base = ref->get_element_type ();
    2899         1647 :   BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings);
    2900         1647 :   ref->element_type = TyVar::subst_covariant_var (base, concrete);
    2901              : 
    2902         1647 :   return ref;
    2903              : }
    2904              : 
    2905              : bool
    2906            0 : SliceType::contains_unsafe_cell () const
    2907              : {
    2908            0 :   return get_element_type ()->contains_unsafe_cell ();
    2909              : }
    2910              : 
    2911              : // BoolType
    2912              : 
    2913         5019 : BoolType::BoolType (HirId ref, std::set<HirId> refs)
    2914              :   : BaseType (ref, ref, KIND,
    2915         5019 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2916        10038 :               refs)
    2917         5019 : {}
    2918              : 
    2919        19374 : BoolType::BoolType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    2920              :   : BaseType (ref, ty_ref, KIND,
    2921        19374 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2922        38748 :               refs)
    2923        19374 : {}
    2924              : 
    2925              : std::string
    2926         2419 : BoolType::get_name () const
    2927              : {
    2928         2419 :   return as_string ();
    2929              : }
    2930              : 
    2931              : void
    2932          262 : BoolType::accept_vis (TyVisitor &vis)
    2933              : {
    2934          262 :   vis.visit (*this);
    2935          262 : }
    2936              : 
    2937              : void
    2938        11195 : BoolType::accept_vis (TyConstVisitor &vis) const
    2939              : {
    2940        11195 :   vis.visit (*this);
    2941        11195 : }
    2942              : 
    2943              : std::string
    2944        43882 : BoolType::as_string () const
    2945              : {
    2946        43882 :   return "bool";
    2947              : }
    2948              : 
    2949              : BaseType *
    2950        19374 : BoolType::clone () const
    2951              : {
    2952        19374 :   return new BoolType (get_ref (), get_ty_ref (), get_combined_refs ());
    2953              : }
    2954              : 
    2955              : // IntType
    2956              : 
    2957        25095 : IntType::IntType (HirId ref, IntKind kind, std::set<HirId> refs)
    2958              :   : BaseType (ref, ref, KIND,
    2959        25095 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2960              :               refs),
    2961        50190 :     int_kind (kind)
    2962        25095 : {}
    2963              : 
    2964       179294 : IntType::IntType (HirId ref, HirId ty_ref, IntKind kind, std::set<HirId> refs)
    2965              :   : BaseType (ref, ty_ref, KIND,
    2966       179294 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    2967              :               refs),
    2968       358588 :     int_kind (kind)
    2969       179294 : {}
    2970              : 
    2971              : std::string
    2972        17446 : IntType::get_name () const
    2973              : {
    2974        17446 :   return as_string ();
    2975              : }
    2976              : 
    2977              : IntType::IntKind
    2978       532083 : IntType::get_int_kind () const
    2979              : {
    2980       532083 :   return int_kind;
    2981              : }
    2982              : 
    2983              : void
    2984         2233 : IntType::accept_vis (TyVisitor &vis)
    2985              : {
    2986         2233 :   vis.visit (*this);
    2987         2233 : }
    2988              : 
    2989              : void
    2990        85627 : IntType::accept_vis (TyConstVisitor &vis) const
    2991              : {
    2992        85627 :   vis.visit (*this);
    2993        85627 : }
    2994              : 
    2995              : std::string
    2996       173154 : IntType::as_string () const
    2997              : {
    2998       173154 :   switch (int_kind)
    2999              :     {
    3000        30262 :     case I8:
    3001        30262 :       return "i8";
    3002        29486 :     case I16:
    3003        29486 :       return "i16";
    3004        58882 :     case I32:
    3005        58882 :       return "i32";
    3006        27628 :     case I64:
    3007        27628 :       return "i64";
    3008        26896 :     case I128:
    3009        26896 :       return "i128";
    3010              :     }
    3011            0 :   rust_unreachable ();
    3012              :   return "__unknown_int_type";
    3013              : }
    3014              : 
    3015              : BaseType *
    3016       179294 : IntType::clone () const
    3017              : {
    3018       179294 :   return new IntType (get_ref (), get_ty_ref (), get_int_kind (),
    3019       179294 :                       get_combined_refs ());
    3020              : }
    3021              : 
    3022              : bool
    3023        86476 : IntType::is_equal (const BaseType &other) const
    3024              : {
    3025        86476 :   if (!BaseType::is_equal (other))
    3026              :     return false;
    3027              : 
    3028        68962 :   const IntType &o = static_cast<const IntType &> (other);
    3029        68962 :   return get_int_kind () == o.get_int_kind ();
    3030              : }
    3031              : 
    3032              : // UintType
    3033              : 
    3034        25095 : UintType::UintType (HirId ref, UintKind kind, std::set<HirId> refs)
    3035              :   : BaseType (ref, ref, KIND,
    3036        25095 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3037              :               refs),
    3038        50190 :     uint_kind (kind)
    3039        25095 : {}
    3040              : 
    3041        97404 : UintType::UintType (HirId ref, HirId ty_ref, UintKind kind,
    3042              :                     std::set<HirId> refs)
    3043              :   : BaseType (ref, ty_ref, KIND,
    3044        97404 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3045              :               refs),
    3046       194808 :     uint_kind (kind)
    3047        97404 : {}
    3048              : 
    3049              : std::string
    3050        12100 : UintType::get_name () const
    3051              : {
    3052        12100 :   return as_string ();
    3053              : }
    3054              : 
    3055              : UintType::UintKind
    3056       367842 : UintType::get_uint_kind () const
    3057              : {
    3058       367842 :   return uint_kind;
    3059              : }
    3060              : 
    3061              : void
    3062          744 : UintType::accept_vis (TyVisitor &vis)
    3063              : {
    3064          744 :   vis.visit (*this);
    3065          744 : }
    3066              : 
    3067              : void
    3068        73847 : UintType::accept_vis (TyConstVisitor &vis) const
    3069              : {
    3070        73847 :   vis.visit (*this);
    3071        73847 : }
    3072              : 
    3073              : std::string
    3074       182808 : UintType::as_string () const
    3075              : {
    3076       182808 :   switch (uint_kind)
    3077              :     {
    3078        41476 :     case U8:
    3079        41476 :       return "u8";
    3080        35129 :     case U16:
    3081        35129 :       return "u16";
    3082        38639 :     case U32:
    3083        38639 :       return "u32";
    3084        38556 :     case U64:
    3085        38556 :       return "u64";
    3086        29008 :     case U128:
    3087        29008 :       return "u128";
    3088              :     }
    3089            0 :   rust_unreachable ();
    3090              :   return "__unknown_uint_type";
    3091              : }
    3092              : 
    3093              : BaseType *
    3094        97404 : UintType::clone () const
    3095              : {
    3096        97404 :   return new UintType (get_ref (), get_ty_ref (), get_uint_kind (),
    3097        97404 :                        get_combined_refs ());
    3098              : }
    3099              : 
    3100              : bool
    3101        62146 : UintType::is_equal (const BaseType &other) const
    3102              : {
    3103        62146 :   if (!BaseType::is_equal (other))
    3104              :     return false;
    3105              : 
    3106        53018 :   const UintType &o = static_cast<const UintType &> (other);
    3107        53018 :   return get_uint_kind () == o.get_uint_kind ();
    3108              : }
    3109              : 
    3110              : // FloatType
    3111              : 
    3112        10038 : FloatType::FloatType (HirId ref, FloatKind kind, std::set<HirId> refs)
    3113              :   : BaseType (ref, ref, KIND,
    3114        10038 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3115              :               refs),
    3116        20076 :     float_kind (kind)
    3117        10038 : {}
    3118              : 
    3119        30785 : FloatType::FloatType (HirId ref, HirId ty_ref, FloatKind kind,
    3120              :                       std::set<HirId> refs)
    3121              :   : BaseType (ref, ty_ref, KIND,
    3122        30785 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3123              :               refs),
    3124        61570 :     float_kind (kind)
    3125        30785 : {}
    3126              : 
    3127              : std::string
    3128         1575 : FloatType::get_name () const
    3129              : {
    3130         1575 :   return as_string ();
    3131              : }
    3132              : 
    3133              : FloatType::FloatKind
    3134        88463 : FloatType::get_float_kind () const
    3135              : {
    3136        88463 :   return float_kind;
    3137              : }
    3138              : 
    3139              : void
    3140          230 : FloatType::accept_vis (TyVisitor &vis)
    3141              : {
    3142          230 :   vis.visit (*this);
    3143          230 : }
    3144              : 
    3145              : void
    3146        17633 : FloatType::accept_vis (TyConstVisitor &vis) const
    3147              : {
    3148        17633 :   vis.visit (*this);
    3149        17633 : }
    3150              : 
    3151              : std::string
    3152        56164 : FloatType::as_string () const
    3153              : {
    3154        56164 :   switch (float_kind)
    3155              :     {
    3156        28745 :     case F32:
    3157        28745 :       return "f32";
    3158        27419 :     case F64:
    3159        27419 :       return "f64";
    3160              :     }
    3161            0 :   rust_unreachable ();
    3162              :   return "__unknown_float_type";
    3163              : }
    3164              : 
    3165              : BaseType *
    3166        30785 : FloatType::clone () const
    3167              : {
    3168        30785 :   return new FloatType (get_ref (), get_ty_ref (), get_float_kind (),
    3169        30785 :                         get_combined_refs ());
    3170              : }
    3171              : 
    3172              : bool
    3173        12684 : FloatType::is_equal (const BaseType &other) const
    3174              : {
    3175        12684 :   if (!BaseType::is_equal (other))
    3176              :     return false;
    3177              : 
    3178        10602 :   const FloatType &o = static_cast<const FloatType &> (other);
    3179        10602 :   return get_float_kind () == o.get_float_kind ();
    3180              : }
    3181              : 
    3182              : // UsizeType
    3183              : 
    3184         5019 : USizeType::USizeType (HirId ref, std::set<HirId> refs)
    3185              :   : BaseType (ref, ref, KIND,
    3186         5019 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3187        10038 :               refs)
    3188         5019 : {}
    3189              : 
    3190        41607 : USizeType::USizeType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    3191              :   : BaseType (ref, ty_ref, KIND,
    3192        41607 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3193        83214 :               refs)
    3194        41607 : {}
    3195              : 
    3196              : std::string
    3197         6900 : USizeType::get_name () const
    3198              : {
    3199         6900 :   return as_string ();
    3200              : }
    3201              : 
    3202              : void
    3203          187 : USizeType::accept_vis (TyVisitor &vis)
    3204              : {
    3205          187 :   vis.visit (*this);
    3206          187 : }
    3207              : 
    3208              : void
    3209        41013 : USizeType::accept_vis (TyConstVisitor &vis) const
    3210              : {
    3211        41013 :   vis.visit (*this);
    3212        41013 : }
    3213              : 
    3214              : std::string
    3215        42235 : USizeType::as_string () const
    3216              : {
    3217        42235 :   return "usize";
    3218              : }
    3219              : 
    3220              : BaseType *
    3221        41607 : USizeType::clone () const
    3222              : {
    3223        41607 :   return new USizeType (get_ref (), get_ty_ref (), get_combined_refs ());
    3224              : }
    3225              : 
    3226              : // ISizeType
    3227              : 
    3228         5299 : ISizeType::ISizeType (HirId ref, std::set<HirId> refs)
    3229              :   : BaseType (ref, ref, KIND,
    3230         5299 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3231        10598 :               refs)
    3232         5299 : {}
    3233              : 
    3234        27167 : ISizeType::ISizeType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    3235              :   : BaseType (ref, ty_ref, KIND,
    3236        27167 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3237        54334 :               refs)
    3238        27167 : {}
    3239              : 
    3240              : std::string
    3241          492 : ISizeType::get_name () const
    3242              : {
    3243          492 :   return as_string ();
    3244              : }
    3245              : 
    3246              : void
    3247           74 : ISizeType::accept_vis (TyVisitor &vis)
    3248              : {
    3249           74 :   vis.visit (*this);
    3250           74 : }
    3251              : 
    3252              : void
    3253        21633 : ISizeType::accept_vis (TyConstVisitor &vis) const
    3254              : {
    3255        21633 :   vis.visit (*this);
    3256        21633 : }
    3257              : 
    3258              : std::string
    3259        12014 : ISizeType::as_string () const
    3260              : {
    3261        12014 :   return "isize";
    3262              : }
    3263              : 
    3264              : BaseType *
    3265        27167 : ISizeType::clone () const
    3266              : {
    3267        27167 :   return new ISizeType (get_ref (), get_ty_ref (), get_combined_refs ());
    3268              : }
    3269              : 
    3270              : // Char Type
    3271              : 
    3272         5019 : CharType::CharType (HirId ref, std::set<HirId> refs)
    3273              :   : BaseType (ref, ref, KIND,
    3274         5019 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3275        10038 :               refs)
    3276         5019 : {}
    3277              : 
    3278         5494 : CharType::CharType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    3279              :   : BaseType (ref, ty_ref, KIND,
    3280         5494 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3281        10988 :               refs)
    3282         5494 : {}
    3283              : 
    3284              : std::string
    3285          261 : CharType::get_name () const
    3286              : {
    3287          261 :   return as_string ();
    3288              : }
    3289              : 
    3290              : void
    3291           47 : CharType::accept_vis (TyVisitor &vis)
    3292              : {
    3293           47 :   vis.visit (*this);
    3294           47 : }
    3295              : 
    3296              : void
    3297         5831 : CharType::accept_vis (TyConstVisitor &vis) const
    3298              : {
    3299         5831 :   vis.visit (*this);
    3300         5831 : }
    3301              : 
    3302              : std::string
    3303         4714 : CharType::as_string () const
    3304              : {
    3305         4714 :   return "char";
    3306              : }
    3307              : 
    3308              : BaseType *
    3309         5494 : CharType::clone () const
    3310              : {
    3311         5494 :   return new CharType (get_ref (), get_ty_ref (), get_combined_refs ());
    3312              : }
    3313              : 
    3314              : // Reference Type
    3315              : 
    3316        32365 : ReferenceType::ReferenceType (HirId ref, TyVar base, Mutability mut,
    3317              :                               Region region, std::set<HirId> refs)
    3318              :   : BaseType (ref, ref, KIND,
    3319        32365 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3320              :               std::move (refs)),
    3321        64730 :     base (base), mut (mut), region (region)
    3322        32365 : {}
    3323              : 
    3324        71179 : ReferenceType::ReferenceType (HirId ref, HirId ty_ref, TyVar base,
    3325              :                               Mutability mut, Region region,
    3326              :                               std::set<HirId> refs)
    3327              :   : BaseType (ref, ty_ref, KIND,
    3328        71179 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3329              :               std::move (refs)),
    3330       142358 :     base (base), mut (mut), region (region)
    3331        71179 : {}
    3332              : 
    3333              : Mutability
    3334       214781 : ReferenceType::mutability () const
    3335              : {
    3336       214781 :   return mut;
    3337              : }
    3338              : 
    3339              : bool
    3340        63168 : ReferenceType::is_mutable () const
    3341              : {
    3342        63168 :   return mut == Mutability::Mut;
    3343              : }
    3344              : Region
    3345        71436 : ReferenceType::get_region () const
    3346              : {
    3347        71436 :   return region;
    3348              : }
    3349              : 
    3350              : bool
    3351         2030 : ReferenceType::is_dyn_object () const
    3352              : {
    3353         4059 :   return is_dyn_slice_type () || is_dyn_str_type () || is_dyn_obj_type ()
    3354         4042 :          || is_dyn_adt_type () || is_dyn_cstr_type ();
    3355              : }
    3356              : 
    3357              : static const TyTy::BaseType *
    3358       131602 : destructure_through_projections (const TyTy::BaseType *t)
    3359              : {
    3360       131602 :   const TyTy::BaseType *element = t->destructure ();
    3361       263826 :   for (int guard = 0; guard < 16; guard++)
    3362              :     {
    3363       132224 :       auto *proj = element->try_as<const TyTy::ProjectionType> ();
    3364          622 :       if (proj == nullptr)
    3365              :         break;
    3366          622 :       auto *normalized = Resolver::normalize_projection (
    3367              :         const_cast<TyTy::ProjectionType *> (proj), BUILTINS_LOCATION,
    3368              :         false /*emit_errors*/, false /*unify_self*/);
    3369          622 :       if (normalized == proj || normalized == nullptr
    3370          622 :           || normalized->get_kind () == TyTy::TypeKind::ERROR)
    3371              :         break;
    3372          622 :       element = normalized->destructure ();
    3373              :     }
    3374       131602 :   return element;
    3375              : }
    3376              : 
    3377              : bool
    3378        21536 : ReferenceType::is_dyn_slice_type (const TyTy::SliceType **slice) const
    3379              : {
    3380        21536 :   const TyTy::BaseType *element = destructure_through_projections (get_base ());
    3381        21536 :   if (element->get_kind () != TyTy::TypeKind::SLICE)
    3382              :     return false;
    3383          663 :   if (slice == nullptr)
    3384              :     return true;
    3385              : 
    3386          662 :   *slice = static_cast<const TyTy::SliceType *> (element);
    3387          662 :   return true;
    3388              : }
    3389              : 
    3390              : bool
    3391        20916 : ReferenceType::is_dyn_str_type (const TyTy::StrType **str) const
    3392              : {
    3393        20916 :   const TyTy::BaseType *element = destructure_through_projections (get_base ());
    3394        20916 :   if (element->get_kind () != TyTy::TypeKind::STR)
    3395              :     return false;
    3396         4171 :   if (str == nullptr)
    3397              :     return true;
    3398              : 
    3399         4162 :   *str = static_cast<const TyTy::StrType *> (element);
    3400         4162 :   return true;
    3401              : }
    3402              : 
    3403              : bool
    3404        16711 : ReferenceType::is_dyn_obj_type (const TyTy::DynamicObjectType **dyn) const
    3405              : {
    3406        16711 :   const TyTy::BaseType *element = destructure_through_projections (get_base ());
    3407        16711 :   if (element->get_kind () != TyTy::TypeKind::DYNAMIC)
    3408              :     return false;
    3409          543 :   if (dyn == nullptr)
    3410              :     return true;
    3411              : 
    3412          526 :   *dyn = static_cast<const TyTy::DynamicObjectType *> (element);
    3413          526 :   return true;
    3414              : }
    3415              : 
    3416              : bool
    3417        16168 : ReferenceType::is_dyn_adt_type (const TyTy::ADTType **adt) const
    3418              : {
    3419        16168 :   const TyTy::BaseType *element = destructure_through_projections (get_base ());
    3420              : 
    3421        16168 :   if (element->get_kind () != TyTy::TypeKind::ADT)
    3422              :     return false;
    3423              : 
    3424         5220 :   const TyTy::ADTType *adt_ty = static_cast<const TyTy::ADTType *> (element);
    3425              : 
    3426         5220 :   if (!adt_ty->is_unsized ())
    3427              :     return false;
    3428           77 :   if (adt != nullptr)
    3429           76 :     *adt = adt_ty;
    3430              : 
    3431              :   return true;
    3432              : }
    3433              : 
    3434              : bool
    3435        16091 : ReferenceType::is_dyn_cstr_type (const TyTy::ADTType **adt) const
    3436              : {
    3437        16091 :   if (get_base ()->get_kind () != TyTy::TypeKind::ADT)
    3438              :     return false;
    3439              : 
    3440         3854 :   const TyTy::ADTType *adt_ty
    3441         3854 :     = static_cast<const TyTy::ADTType *> (get_base ());
    3442         3854 :   auto &mappings = Analysis::Mappings::get ();
    3443         3854 :   auto cstr_item = mappings.lookup_lang_item (LangItem::Kind::CSTR);
    3444              : 
    3445         3854 :   if (!cstr_item.has_value ())
    3446              :     return false;
    3447              : 
    3448            0 :   if (cstr_item.value () != adt_ty->get_id ())
    3449            0 :     return false;
    3450              : 
    3451            0 :   *adt = adt_ty;
    3452            0 :   return true;
    3453              : }
    3454              : 
    3455              : void
    3456        11408 : ReferenceType::accept_vis (TyVisitor &vis)
    3457              : {
    3458        11408 :   vis.visit (*this);
    3459        11408 : }
    3460              : 
    3461              : void
    3462        20440 : ReferenceType::accept_vis (TyConstVisitor &vis) const
    3463              : {
    3464        20440 :   vis.visit (*this);
    3465        20440 : }
    3466              : 
    3467              : std::string
    3468        15733 : ReferenceType::as_string () const
    3469              : {
    3470        61895 :   return std::string ("&") + (is_mutable () ? "mut" : "") + " "
    3471        31466 :          + get_base ()->as_string ();
    3472              : }
    3473              : 
    3474              : std::string
    3475          640 : ReferenceType::get_name () const
    3476              : {
    3477         2434 :   return std::string ("&") + (is_mutable () ? "mut" : "") + " "
    3478         1280 :          + get_base ()->get_name ();
    3479              : }
    3480              : 
    3481              : bool
    3482        42817 : ReferenceType::is_equal (const BaseType &other) const
    3483              : {
    3484        42817 :   if (get_kind () != other.get_kind ())
    3485              :     return false;
    3486              : 
    3487        42038 :   auto other2 = static_cast<const ReferenceType &> (other);
    3488        42038 :   if (mutability () != other2.mutability ())
    3489              :     return false;
    3490              : 
    3491        37689 :   return get_base ()->is_equal (*other2.get_base ());
    3492        42038 : }
    3493              : 
    3494              : BaseType *
    3495       572195 : ReferenceType::get_base () const
    3496              : {
    3497       572195 :   return base.get_tyty ();
    3498              : }
    3499              : 
    3500              : const TyVar &
    3501         3342 : ReferenceType::get_var_element_type () const
    3502              : {
    3503         3342 :   return base;
    3504              : }
    3505              : 
    3506              : BaseType *
    3507        70881 : ReferenceType::clone () const
    3508              : {
    3509        70881 :   return new ReferenceType (get_ref (), get_ty_ref (), base, mutability (),
    3510        70881 :                             get_region (), get_combined_refs ());
    3511              : }
    3512              : 
    3513              : ReferenceType *
    3514        11151 : ReferenceType::handle_substitions (SubstitutionArgumentMappings &mappings)
    3515              : {
    3516        11151 :   auto &mappings_table = Analysis::Mappings::get ();
    3517              : 
    3518        11151 :   ReferenceType *ref = static_cast<ReferenceType *> (clone ());
    3519        11151 :   ref->set_ty_ref (mappings_table.get_next_hir_id ());
    3520              : 
    3521              :   // might be &T or &ADT so this needs to be recursive
    3522        11151 :   auto base = ref->get_base ();
    3523        11151 :   BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings);
    3524        11151 :   ref->base = TyVar::subst_covariant_var (base, concrete);
    3525              : 
    3526        11151 :   return ref;
    3527              : }
    3528              : 
    3529              : // PointerType
    3530              : 
    3531        15207 : PointerType::PointerType (HirId ref, TyVar base, Mutability mut,
    3532              :                           std::set<HirId> refs)
    3533              :   : BaseType (ref, ref, KIND,
    3534        15207 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3535              :               refs),
    3536        30414 :     base (base), mut (mut)
    3537        15207 : {}
    3538              : 
    3539        18779 : PointerType::PointerType (HirId ref, HirId ty_ref, TyVar base, Mutability mut,
    3540              :                           std::set<HirId> refs)
    3541              :   : BaseType (ref, ty_ref, KIND,
    3542        18779 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    3543              :               refs),
    3544        37558 :     base (base), mut (mut)
    3545        18779 : {}
    3546              : 
    3547              : Mutability
    3548        79175 : PointerType::mutability () const
    3549              : {
    3550        79175 :   return mut;
    3551              : }
    3552              : 
    3553              : bool
    3554        34160 : PointerType::is_mutable () const
    3555              : {
    3556        34160 :   return mut == Mutability::Mut;
    3557              : }
    3558              : 
    3559              : bool
    3560          326 : PointerType::is_const () const
    3561              : {
    3562          326 :   return mut == Mutability::Imm;
    3563              : }
    3564              : 
    3565              : bool
    3566         4507 : PointerType::is_dyn_object () const
    3567              : {
    3568         9014 :   return is_dyn_slice_type () || is_dyn_str_type () || is_dyn_obj_type ()
    3569         9014 :          || is_dyn_adt_type ();
    3570              : }
    3571              : 
    3572              : bool
    3573        15840 : PointerType::is_dyn_slice_type (const TyTy::SliceType **slice) const
    3574              : {
    3575        15840 :   const TyTy::BaseType *element = destructure_through_projections (get_base ());
    3576        15840 :   if (element->get_kind () != TyTy::TypeKind::SLICE)
    3577              :     return false;
    3578          576 :   if (slice == nullptr)
    3579              :     return true;
    3580              : 
    3581          576 :   *slice = static_cast<const TyTy::SliceType *> (element);
    3582          576 :   return true;
    3583              : }
    3584              : 
    3585              : bool
    3586        15264 : PointerType::is_dyn_str_type (const TyTy::StrType **str) const
    3587              : {
    3588        15264 :   const TyTy::BaseType *element = destructure_through_projections (get_base ());
    3589        15264 :   if (element->get_kind () != TyTy::TypeKind::STR)
    3590              :     return false;
    3591         2671 :   if (str == nullptr)
    3592              :     return true;
    3593              : 
    3594         2671 :   *str = static_cast<const TyTy::StrType *> (element);
    3595         2671 :   return true;
    3596              : }
    3597              : 
    3598              : bool
    3599        12593 : PointerType::is_dyn_obj_type (const TyTy::DynamicObjectType **dyn) const
    3600              : {
    3601        12593 :   const TyTy::BaseType *element = destructure_through_projections (get_base ());
    3602        12593 :   if (element->get_kind () != TyTy::TypeKind::DYNAMIC)
    3603              :     return false;
    3604           19 :   if (dyn == nullptr)
    3605              :     return true;
    3606              : 
    3607           19 :   *dyn = static_cast<const TyTy::DynamicObjectType *> (element);
    3608           19 :   return true;
    3609              : }
    3610              : 
    3611              : bool
    3612        12574 : PointerType::is_dyn_adt_type (const TyTy::ADTType **adt) const
    3613              : {
    3614        12574 :   const TyTy::BaseType *element = destructure_through_projections (get_base ());
    3615        12574 :   if (element->get_kind () != TyTy::TypeKind::ADT)
    3616              :     return false;
    3617              : 
    3618          162 :   const TyTy::ADTType *adt_ty = static_cast<const TyTy::ADTType *> (element);
    3619              : 
    3620          162 :   if (!adt_ty->is_unsized ())
    3621              :     return false;
    3622           21 :   if (adt != nullptr)
    3623           21 :     *adt = adt_ty;
    3624              : 
    3625              :   return true;
    3626              : }
    3627              : 
    3628              : void
    3629         3630 : PointerType::accept_vis (TyVisitor &vis)
    3630              : {
    3631         3630 :   vis.visit (*this);
    3632         3630 : }
    3633              : 
    3634              : void
    3635        12487 : PointerType::accept_vis (TyConstVisitor &vis) const
    3636              : {
    3637        12487 :   vis.visit (*this);
    3638        12487 : }
    3639              : 
    3640              : std::string
    3641         3734 : PointerType::as_string () const
    3642              : {
    3643        13279 :   return std::string ("* ") + (is_mutable () ? "mut" : "const") + " "
    3644         7468 :          + get_base ()->as_string ();
    3645              : }
    3646              : 
    3647              : std::string
    3648           10 : PointerType::get_name () const
    3649              : {
    3650           30 :   return std::string ("* ") + (is_mutable () ? "mut" : "const") + " "
    3651           20 :          + get_base ()->get_name ();
    3652              : }
    3653              : 
    3654              : bool
    3655        18017 : PointerType::is_equal (const BaseType &other) const
    3656              : {
    3657        18017 :   if (get_kind () != other.get_kind ())
    3658              :     return false;
    3659              : 
    3660        17602 :   auto other2 = static_cast<const PointerType &> (other);
    3661        17602 :   if (mutability () != other2.mutability ())
    3662              :     return false;
    3663              : 
    3664        17494 :   return get_base ()->is_equal (*other2.get_base ());
    3665        17602 : }
    3666              : 
    3667              : BaseType *
    3668       182749 : PointerType::get_base () const
    3669              : {
    3670       182749 :   return base.get_tyty ();
    3671              : }
    3672              : 
    3673              : const TyVar &
    3674          643 : PointerType::get_var_element_type () const
    3675              : {
    3676          643 :   return base;
    3677              : }
    3678              : 
    3679              : BaseType *
    3680        18136 : PointerType::clone () const
    3681              : {
    3682        18136 :   return new PointerType (get_ref (), get_ty_ref (), base, mutability (),
    3683        18136 :                           get_combined_refs ());
    3684              : }
    3685              : 
    3686              : PointerType *
    3687         3403 : PointerType::handle_substitions (SubstitutionArgumentMappings &mappings)
    3688              : {
    3689         3403 :   auto &mappings_table = Analysis::Mappings::get ();
    3690              : 
    3691         3403 :   PointerType *ref = static_cast<PointerType *> (clone ());
    3692         3403 :   ref->set_ty_ref (mappings_table.get_next_hir_id ());
    3693              : 
    3694              :   // might be &T or &ADT so this needs to be recursive
    3695         3403 :   auto base = ref->get_base ();
    3696         3403 :   BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings);
    3697         3403 :   ref->base = TyVar::subst_covariant_var (base, concrete);
    3698              : 
    3699         3403 :   return ref;
    3700              : }
    3701              : 
    3702              : // PARAM Type
    3703              : 
    3704        14088 : ParamType::ParamType (std::string symbol, location_t locus, HirId ref,
    3705              :                       std::vector<TypeBoundPredicate> specified_bounds,
    3706              :                       std::set<HirId> refs)
    3707              :   : BaseGeneric (ref, ref, KIND,
    3708        28176 :                  {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, symbol),
    3709              :                   locus},
    3710              :                  std::move (specified_bounds), refs),
    3711        42264 :     is_trait_self (false), symbol (symbol)
    3712        14088 : {}
    3713              : 
    3714      5796202 : ParamType::ParamType (bool is_trait_self, std::string symbol, location_t locus,
    3715              :                       HirId ref, HirId ty_ref,
    3716              :                       std::vector<TypeBoundPredicate> specified_bounds,
    3717              :                       std::set<HirId> refs)
    3718              :   : BaseGeneric (ref, ty_ref, KIND,
    3719     11592404 :                  {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, symbol),
    3720              :                   locus},
    3721              :                  std::move (specified_bounds), refs),
    3722     17388606 :     is_trait_self (is_trait_self), symbol (symbol)
    3723      5796202 : {}
    3724              : 
    3725              : bool
    3726       720299 : ParamType::can_resolve () const
    3727              : {
    3728       720299 :   return get_ref () != get_ty_ref ();
    3729              : }
    3730              : 
    3731              : void
    3732        76759 : ParamType::accept_vis (TyVisitor &vis)
    3733              : {
    3734        76759 :   vis.visit (*this);
    3735        76759 : }
    3736              : 
    3737              : void
    3738          301 : ParamType::accept_vis (TyConstVisitor &vis) const
    3739              : {
    3740          301 :   vis.visit (*this);
    3741          301 : }
    3742              : 
    3743              : std::string
    3744        18281 : ParamType::as_string () const
    3745              : {
    3746        18281 :   if (!can_resolve ())
    3747              :     {
    3748           22 :       return get_symbol () + " REF: " + std::to_string (get_ref ());
    3749              :     }
    3750              : 
    3751        18270 :   BaseType *lookup = resolve ();
    3752        36540 :   return get_symbol () + "=" + lookup->as_string ();
    3753              : }
    3754              : 
    3755              : std::string
    3756        37465 : ParamType::get_name () const
    3757              : {
    3758        37465 :   if (!can_resolve ())
    3759         3940 :     return get_symbol ();
    3760              : 
    3761        34943 :   static std::vector<const ParamType *> active;
    3762        67050 :   if (Resolver::ScopedPush<const ParamType *>::contains (active, this))
    3763            0 :     return get_symbol ();
    3764              : 
    3765        33525 :   Resolver::ScopedPush<const ParamType *> guard (active, this);
    3766              : 
    3767        33525 :   return destructure ()->get_name ();
    3768        33525 : }
    3769              : 
    3770              : BaseType *
    3771      5796202 : ParamType::clone () const
    3772              : {
    3773      5796202 :   return new ParamType (is_trait_self, get_symbol (), ident.locus, get_ref (),
    3774              :                         get_ty_ref (), get_specified_bounds (),
    3775     11592404 :                         get_combined_refs ());
    3776              : }
    3777              : 
    3778              : std::string
    3779      6354375 : ParamType::get_symbol () const
    3780              : {
    3781      6354375 :   return symbol;
    3782              : }
    3783              : 
    3784              : BaseType *
    3785       780430 : ParamType::resolve () const
    3786              : {
    3787       780430 :   TyVar var (get_ty_ref ());
    3788       780430 :   BaseType *r = var.get_tyty ();
    3789              : 
    3790      1567792 :   while (r->get_kind () == TypeKind::PARAM)
    3791              :     {
    3792       503520 :       ParamType *rr = static_cast<ParamType *> (r);
    3793       503520 :       if (!rr->can_resolve ())
    3794              :         break;
    3795              : 
    3796         6932 :       TyVar v (rr->get_ty_ref ());
    3797         6932 :       BaseType *n = v.get_tyty ();
    3798              : 
    3799              :       // fix infinite loop
    3800         6932 :       if (r == n)
    3801              :         break;
    3802              : 
    3803         6932 :       r = n;
    3804              :     }
    3805              : 
    3806       780430 :   if (r->get_kind () == TypeKind::PARAM && (r->get_ref () == r->get_ty_ref ()))
    3807       496588 :     return TyVar (r->get_ty_ref ()).get_tyty ();
    3808              : 
    3809              :   return r;
    3810              : }
    3811              : 
    3812              : bool
    3813        52581 : ParamType::is_equal (const BaseType &other) const
    3814              : {
    3815        52581 :   if (get_kind () != other.get_kind ())
    3816              :     {
    3817        14482 :       if (!can_resolve ())
    3818              :         return false;
    3819              : 
    3820        10874 :       return resolve ()->is_equal (other);
    3821              :     }
    3822              : 
    3823        38099 :   auto other2 = static_cast<const ParamType &> (other);
    3824        38099 :   if (can_resolve () != other2.can_resolve ())
    3825              :     return false;
    3826              : 
    3827        36404 :   if (can_resolve ())
    3828        24424 :     return Resolver::types_compatable (TyTy::TyWithLocation (resolve ()),
    3829        24424 :                                        TyTy::TyWithLocation (other2.resolve ()),
    3830              :                                        UNKNOWN_LOCATION, false, false);
    3831              : 
    3832        11980 :   return get_symbol ().compare (other2.get_symbol ()) == 0;
    3833        38099 : }
    3834              : 
    3835              : ParamType *
    3836        75214 : ParamType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
    3837              : {
    3838        75214 :   SubstitutionArg arg = SubstitutionArg::error ();
    3839        75214 :   bool ok = subst_mappings.get_argument_for_symbol (this, &arg);
    3840        75214 :   if (!ok || arg.is_error ())
    3841              :     return this;
    3842              : 
    3843        58294 :   ParamType *p = static_cast<ParamType *> (clone ());
    3844        58294 :   const BaseType *resolved = arg.get_tyty ();
    3845        58294 :   if (resolved->get_kind () == TyTy::TypeKind::PARAM)
    3846              :     {
    3847         9348 :       const ParamType &pp = *static_cast<const ParamType *> (resolved);
    3848         9348 :       if (pp.can_resolve ())
    3849         8727 :         pp.resolve ();
    3850              :     }
    3851              : 
    3852              :   // this is the new subst that this needs to pass
    3853        58294 :   p->set_ref (mappings.get_next_hir_id ());
    3854        58294 :   p->set_ty_ref (arg.get_tyty ()->get_ref ());
    3855              : 
    3856        58294 :   return p;
    3857              : }
    3858              : 
    3859              : void
    3860         4182 : ParamType::set_implicit_self_trait ()
    3861              : {
    3862         4182 :   is_trait_self = true;
    3863         4182 : }
    3864              : 
    3865              : bool
    3866        39788 : ParamType::is_implicit_self_trait () const
    3867              : {
    3868        39788 :   return is_trait_self;
    3869              : }
    3870              : 
    3871              : static std::string
    3872         2636 : generate_tree_str (tree value)
    3873              : {
    3874         2636 :   pretty_printer pp;
    3875         2636 :   dump_generic_node (&pp, value, 0, TDF_NONE, true);
    3876         2636 :   std::string result = pp_formatted_text (&pp);
    3877              : 
    3878         5272 :   if (!result.empty () && result.back () == '\n')
    3879            0 :     result.pop_back ();
    3880              : 
    3881         5272 :   return result;
    3882         2636 : }
    3883              : 
    3884              : // ---
    3885              : 
    3886          723 : ConstParamType::ConstParamType (std::string symbol, location_t locus,
    3887              :                                 BaseType *type, HirId ref, HirId ty_ref,
    3888              :                                 std::set<HirId> refs)
    3889              :   : BaseConstType (type),
    3890              :     BaseGeneric (ref, ty_ref, KIND,
    3891         1446 :                  {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, symbol),
    3892              :                   locus},
    3893              :                  {}, refs),
    3894         2169 :     symbol (symbol)
    3895          723 : {}
    3896              : 
    3897              : BaseConstType::ConstKind
    3898         4941 : ConstParamType::const_kind () const
    3899              : {
    3900         4941 :   return BaseConstType::ConstKind::Decl;
    3901              : }
    3902              : 
    3903              : std::string
    3904         1995 : ConstParamType::get_symbol () const
    3905              : {
    3906         1995 :   return symbol;
    3907              : }
    3908              : 
    3909              : bool
    3910         1279 : ConstParamType::can_resolve () const
    3911              : {
    3912         1279 :   return get_ref () != get_ty_ref ();
    3913              : }
    3914              : 
    3915              : BaseType *
    3916         2803 : ConstParamType::resolve () const
    3917              : {
    3918         2803 :   TyVar var (get_ty_ref ());
    3919         2803 :   BaseType *r = var.get_tyty ();
    3920              : 
    3921         5718 :   while (r->get_kind () == TypeKind::CONST)
    3922              :     {
    3923         2915 :       TyVar v (r->get_ty_ref ());
    3924         2915 :       BaseType *n = v.get_tyty ();
    3925              : 
    3926              :       // fix infinite loop
    3927         2915 :       if (r == n)
    3928              :         break;
    3929              : 
    3930          112 :       r = n;
    3931              :     }
    3932              : 
    3933         2803 :   if (r->get_kind () == TypeKind::CONST && (r->get_ref () == r->get_ty_ref ()))
    3934              :     {
    3935         2803 :       auto *const_type = r->as_const_type ();
    3936         2803 :       if (const_type->const_kind () != BaseConstType::ConstKind::Value)
    3937         1316 :         return TyVar (r->get_ty_ref ()).get_tyty ();
    3938              :     }
    3939              : 
    3940              :   return r;
    3941              : }
    3942              : 
    3943              : void
    3944           63 : ConstParamType::accept_vis (TyVisitor &vis)
    3945              : {
    3946           63 :   vis.visit (*this);
    3947           63 : }
    3948              : 
    3949              : void
    3950            0 : ConstParamType::accept_vis (TyConstVisitor &vis) const
    3951              : {
    3952            0 :   vis.visit (*this);
    3953            0 : }
    3954              : 
    3955              : std::string
    3956            0 : ConstParamType::as_string () const
    3957              : {
    3958            0 :   if (!can_resolve ())
    3959              :     {
    3960            0 :       return get_symbol () + " CONST_REF: " + std::to_string (get_ref ());
    3961              :     }
    3962              : 
    3963            0 :   BaseType *lookup = resolve ();
    3964              :   // Avoid infinite recursion if resolve() returns this same type
    3965            0 :   if (lookup == this->as_base_type ())
    3966              :     {
    3967            0 :       return get_symbol () + " CONST_REF: " + std::to_string (get_ref ());
    3968              :     }
    3969              : 
    3970            0 :   return get_symbol () + "=" + lookup->as_string ();
    3971              : }
    3972              : 
    3973              : BaseType *
    3974          588 : ConstParamType::clone () const
    3975              : {
    3976         1176 :   return new ConstParamType (get_symbol (), ident.locus, specified_type,
    3977         1176 :                              get_ref (), get_ty_ref (), get_combined_refs ());
    3978              : }
    3979              : 
    3980              : std::string
    3981          259 : ConstParamType::get_name () const
    3982              : {
    3983          259 :   if (!can_resolve ())
    3984           56 :     return get_symbol ();
    3985              : 
    3986          203 :   BaseType *lookup = resolve ();
    3987          203 :   if (lookup == this->as_base_type ())
    3988            0 :     return get_symbol () + ":" + get_specified_type ()->get_name ();
    3989              : 
    3990          203 :   return lookup->get_name ();
    3991              : }
    3992              : 
    3993              : bool
    3994          319 : ConstParamType::is_equal (const BaseType &other) const
    3995              : {
    3996          319 :   if (get_kind () != other.get_kind ())
    3997              :     {
    3998            1 :       if (!can_resolve ())
    3999              :         return false;
    4000              : 
    4001            0 :       return resolve ()->is_equal (other);
    4002              :     }
    4003              : 
    4004          318 :   auto other_const = other.as_const_type ();
    4005          318 :   if (other_const->const_kind () != BaseConstType::ConstKind::Decl)
    4006              :     return false;
    4007              : 
    4008          311 :   auto &other2 = static_cast<const ConstParamType &> (*other_const);
    4009          311 :   if (can_resolve () != other2.can_resolve ())
    4010              :     return false;
    4011              : 
    4012          276 :   if (can_resolve ())
    4013              :     {
    4014              :       // Compare the resolved ty_ref values to avoid infinite recursion
    4015              :       // through types_compatable/unification
    4016          233 :       BaseType *lhs = resolve ();
    4017          233 :       BaseType *rhs = other2.resolve ();
    4018              : 
    4019              :       // If they resolve to the same type (same ty_ref), they're equal
    4020          233 :       if (lhs->get_ty_ref () == rhs->get_ty_ref ())
    4021              :         return true;
    4022              : 
    4023              :       // Otherwise check if the resolved types are equal
    4024              :       // Avoid recursion by checking if we'd be comparing ConstParamTypes again
    4025          200 :       if (lhs->get_kind () == TypeKind::CONST
    4026          200 :           && lhs->as_const_type ()->const_kind ()
    4027              :                == BaseConstType::ConstKind::Decl)
    4028              :         return false; // Would cause recursion, so not equal
    4029              : 
    4030          200 :       return lhs->is_equal (*rhs);
    4031              :     }
    4032              : 
    4033           43 :   return get_symbol ().compare (other2.get_symbol ()) == 0;
    4034              : }
    4035              : 
    4036              : BaseType *
    4037           63 : ConstParamType::handle_substitions (
    4038              :   SubstitutionArgumentMappings &subst_mappings)
    4039              : {
    4040           63 :   SubstitutionArg arg = SubstitutionArg::error ();
    4041           63 :   bool ok = subst_mappings.get_argument_for_symbol (this, &arg);
    4042           63 :   if (!ok || arg.is_error ())
    4043            0 :     return this;
    4044              : 
    4045           63 :   ConstParamType *p = static_cast<ConstParamType *> (clone ());
    4046           63 :   const BaseType *resolved = arg.get_tyty ();
    4047              : 
    4048              :   // this is the new subst that this needs to pass
    4049           63 :   p->set_ref (mappings.get_next_hir_id ());
    4050           63 :   p->set_ty_ref (resolved->get_ref ());
    4051              : 
    4052           63 :   return p;
    4053              : }
    4054              : 
    4055              : // --- ConstValueType
    4056              : 
    4057         3364 : ConstValueType::ConstValueType (tree value, BaseType *type, HirId ref,
    4058              :                                 HirId ty_ref, std::set<HirId> refs)
    4059              :   : BaseType (ref, ty_ref, KIND,
    4060         3364 :               {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
    4061              :               refs),
    4062         6728 :     BaseConstType (type), folded_val (value)
    4063         3364 : {}
    4064              : 
    4065              : BaseConstType::ConstKind
    4066        55844 : ConstValueType::const_kind () const
    4067              : {
    4068        55844 :   return BaseConstType::ConstKind::Value;
    4069              : }
    4070              : 
    4071              : void
    4072            0 : ConstValueType::accept_vis (TyVisitor &vis)
    4073              : {
    4074            0 :   vis.visit (*this);
    4075            0 : }
    4076              : 
    4077              : void
    4078            0 : ConstValueType::accept_vis (TyConstVisitor &vis) const
    4079              : {
    4080            0 :   vis.visit (*this);
    4081            0 : }
    4082              : 
    4083              : std::string
    4084         2636 : ConstValueType::as_string () const
    4085              : {
    4086         2636 :   return generate_tree_str (folded_val);
    4087              : }
    4088              : 
    4089              : BaseType *
    4090          170 : ConstValueType::clone () const
    4091              : {
    4092          340 :   return new ConstValueType (folded_val, specified_type, get_ref (),
    4093          170 :                              get_ty_ref (), get_combined_refs ());
    4094              : }
    4095              : 
    4096              : std::string
    4097          203 : ConstValueType::get_name () const
    4098              : {
    4099          203 :   return as_string ();
    4100              : }
    4101              : 
    4102              : bool
    4103         2031 : ConstValueType::is_equal (const BaseType &other) const
    4104              : {
    4105         2031 :   if (get_kind () != other.get_kind ())
    4106              :     return false;
    4107              : 
    4108         2031 :   auto other_const = other.as_const_type ();
    4109         2031 :   if (other_const->const_kind () != BaseConstType::ConstKind::Value)
    4110              :     return false;
    4111              : 
    4112         1962 :   auto &other2 = static_cast<const ConstValueType &> (*other_const);
    4113         1962 :   return folded_val == other2.folded_val;
    4114              : }
    4115              : 
    4116              : tree
    4117         8694 : ConstValueType::get_value () const
    4118              : {
    4119         8694 :   return folded_val;
    4120              : }
    4121              : 
    4122              : // --- ConstInferType
    4123              : 
    4124          109 : ConstInferType::ConstInferType (BaseType *type, HirId ref, HirId ty_ref,
    4125              :                                 std::set<HirId> refs)
    4126              :   : BaseType (ref, ty_ref, KIND,
    4127          109 :               {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
    4128              :               refs),
    4129          218 :     BaseConstType (type)
    4130          109 : {}
    4131              : 
    4132              : BaseConstType::ConstKind
    4133          921 : ConstInferType::const_kind () const
    4134              : {
    4135          921 :   return BaseConstType::ConstKind::Infer;
    4136              : }
    4137              : 
    4138              : void
    4139            0 : ConstInferType::accept_vis (TyVisitor &vis)
    4140              : {
    4141            0 :   vis.visit (*this);
    4142            0 : }
    4143              : 
    4144              : void
    4145            0 : ConstInferType::accept_vis (TyConstVisitor &vis) const
    4146              : {
    4147            0 :   vis.visit (*this);
    4148            0 : }
    4149              : 
    4150              : std::string
    4151            0 : ConstInferType::as_string () const
    4152              : {
    4153            0 :   return specified_type->get_name () + "-?";
    4154              : }
    4155              : 
    4156              : BaseType *
    4157            0 : ConstInferType::clone () const
    4158              : {
    4159            0 :   auto &mappings = Analysis::Mappings::get ();
    4160            0 :   auto context = Resolver::TypeCheckContext::get ();
    4161              : 
    4162            0 :   ConstInferType *clone
    4163            0 :     = new ConstInferType (specified_type, mappings.get_next_hir_id (),
    4164            0 :                           get_ty_ref (), get_combined_refs ());
    4165              : 
    4166            0 :   context->insert_type (Analysis::NodeMapping (mappings.get_current_crate (),
    4167              :                                                UNKNOWN_NODEID,
    4168              :                                                clone->get_ref (),
    4169            0 :                                                UNKNOWN_LOCAL_DEFID),
    4170              :                         clone);
    4171            0 :   mappings.insert_location (clone->get_ref (),
    4172              :                             mappings.lookup_location (get_ref ()));
    4173              : 
    4174            0 :   clone->append_reference (get_ref ());
    4175              : 
    4176            0 :   return clone;
    4177              : }
    4178              : 
    4179              : std::string
    4180            0 : ConstInferType::get_name () const
    4181              : {
    4182            0 :   return as_string ();
    4183              : }
    4184              : 
    4185              : bool
    4186           46 : ConstInferType::is_equal (const BaseType &other) const
    4187              : {
    4188           46 :   if (get_kind () != other.get_kind ())
    4189              :     return false;
    4190              : 
    4191           46 :   auto other_const = other.as_const_type ();
    4192           46 :   if (other_const->const_kind () != BaseConstType::ConstKind::Infer)
    4193              :     return false;
    4194              : 
    4195            0 :   return get_ref () == other.get_ref ();
    4196              : }
    4197              : 
    4198              : // --- ConstErrorType
    4199              : 
    4200            1 : ConstErrorType::ConstErrorType (BaseType *type, HirId ref, HirId ty_ref,
    4201              :                                 std::set<HirId> refs)
    4202              :   : BaseType (ref, ty_ref, KIND,
    4203            1 :               {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
    4204              :               refs),
    4205            2 :     BaseConstType (type)
    4206            1 : {}
    4207              : 
    4208              : BaseConstType::ConstKind
    4209            0 : ConstErrorType::const_kind () const
    4210              : {
    4211            0 :   return BaseConstType::ConstKind::Error;
    4212              : }
    4213              : 
    4214              : void
    4215            0 : ConstErrorType::accept_vis (TyVisitor &vis)
    4216              : {
    4217            0 :   vis.visit (*this);
    4218            0 : }
    4219              : 
    4220              : void
    4221            0 : ConstErrorType::accept_vis (TyConstVisitor &vis) const
    4222              : {
    4223            0 :   vis.visit (*this);
    4224            0 : }
    4225              : 
    4226              : std::string
    4227            0 : ConstErrorType::as_string () const
    4228              : {
    4229            0 :   return "<const_error>";
    4230              : }
    4231              : 
    4232              : BaseType *
    4233            0 : ConstErrorType::clone () const
    4234              : {
    4235            0 :   return new ConstErrorType (specified_type, get_ref (), get_ty_ref (),
    4236            0 :                              get_combined_refs ());
    4237              : }
    4238              : 
    4239              : std::string
    4240            0 : ConstErrorType::get_name () const
    4241              : {
    4242            0 :   return as_string ();
    4243              : }
    4244              : 
    4245              : bool
    4246            0 : ConstErrorType::is_equal (const BaseType &other) const
    4247              : {
    4248            0 :   if (get_kind () != other.get_kind ())
    4249              :     return false;
    4250              : 
    4251            0 :   auto other_const = other.as_const_type ();
    4252            0 :   return other_const->const_kind () == BaseConstType::ConstKind::Error;
    4253              : }
    4254              : 
    4255              : // OpaqueType
    4256              : 
    4257           37 : OpaqueType::OpaqueType (location_t locus, HirId ref,
    4258              :                         std::vector<TypeBoundPredicate> specified_bounds,
    4259              :                         std::set<HirId> refs)
    4260              :   : BaseType (ref, ref, KIND,
    4261           74 :               {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, "impl"),
    4262              :                locus},
    4263          111 :               specified_bounds, refs)
    4264           37 : {}
    4265              : 
    4266           57 : OpaqueType::OpaqueType (location_t locus, HirId ref, HirId ty_ref,
    4267              :                         std::vector<TypeBoundPredicate> specified_bounds,
    4268              :                         std::set<HirId> refs)
    4269              :   : BaseType (ref, ty_ref, KIND,
    4270          114 :               {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, "impl"),
    4271              :                locus},
    4272          171 :               specified_bounds, refs)
    4273           57 : {}
    4274              : 
    4275              : bool
    4276          784 : OpaqueType::can_resolve () const
    4277              : {
    4278          784 :   return get_ref () != get_ty_ref ();
    4279              : }
    4280              : 
    4281              : void
    4282            0 : OpaqueType::accept_vis (TyVisitor &vis)
    4283              : {
    4284            0 :   vis.visit (*this);
    4285            0 : }
    4286              : 
    4287              : void
    4288            0 : OpaqueType::accept_vis (TyConstVisitor &vis) const
    4289              : {
    4290            0 :   vis.visit (*this);
    4291            0 : }
    4292              : 
    4293              : std::string
    4294           84 : OpaqueType::as_string () const
    4295              : {
    4296           84 :   return get_name ();
    4297              : }
    4298              : 
    4299              : std::string
    4300           84 : OpaqueType::get_name () const
    4301              : {
    4302           84 :   return "impl " + raw_bounds_as_name ();
    4303              : }
    4304              : 
    4305              : BaseType *
    4306           57 : OpaqueType::clone () const
    4307              : {
    4308          114 :   return new OpaqueType (ident.locus, get_ref (), get_ty_ref (),
    4309           57 :                          get_specified_bounds (), get_combined_refs ());
    4310              : }
    4311              : 
    4312              : BaseType *
    4313         1045 : OpaqueType::resolve () const
    4314              : {
    4315         1045 :   TyVar var (get_ty_ref ());
    4316         1045 :   return var.get_tyty ();
    4317              : }
    4318              : 
    4319              : bool
    4320          238 : OpaqueType::is_equal (const BaseType &other) const
    4321              : {
    4322          238 :   auto other2 = static_cast<const OpaqueType &> (other);
    4323          238 :   if (can_resolve () != other2.can_resolve ())
    4324              :     return false;
    4325              : 
    4326          203 :   if (num_specified_bounds () != other.num_specified_bounds ())
    4327              :     return false;
    4328              : 
    4329          392 :   for (const auto &pred : specified_bounds)
    4330              :     {
    4331          196 :       bool found = false;
    4332          196 :       for (const auto &opred : other.get_specified_bounds ())
    4333              :         {
    4334          196 :           found = pred.is_equal (opred);
    4335          196 :           if (found)
    4336              :             break;
    4337              :         }
    4338              : 
    4339          196 :       if (!found)
    4340          238 :         return false;
    4341              :     }
    4342              : 
    4343              :   return true;
    4344          238 : }
    4345              : 
    4346              : // StrType
    4347              : 
    4348         5019 : StrType::StrType (HirId ref, std::set<HirId> refs)
    4349              :   : BaseType (ref, ref, KIND,
    4350         5019 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4351        10038 :               refs)
    4352         5019 : {}
    4353              : 
    4354         3901 : StrType::StrType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    4355              :   : BaseType (ref, ty_ref, KIND,
    4356         3901 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4357         7802 :               refs)
    4358         3901 : {}
    4359              : 
    4360              : std::string
    4361          112 : StrType::get_name () const
    4362              : {
    4363          112 :   return as_string ();
    4364              : }
    4365              : 
    4366              : BaseType *
    4367         3901 : StrType::clone () const
    4368              : {
    4369         3901 :   return new StrType (get_ref (), get_ty_ref (), get_combined_refs ());
    4370              : }
    4371              : 
    4372              : void
    4373            8 : StrType::accept_vis (TyVisitor &vis)
    4374              : {
    4375            8 :   vis.visit (*this);
    4376            8 : }
    4377              : 
    4378              : void
    4379         4796 : StrType::accept_vis (TyConstVisitor &vis) const
    4380              : {
    4381         4796 :   vis.visit (*this);
    4382         4796 : }
    4383              : 
    4384              : std::string
    4385         4577 : StrType::as_string () const
    4386              : {
    4387         4577 :   return "str";
    4388              : }
    4389              : 
    4390              : bool
    4391        14417 : StrType::is_equal (const BaseType &other) const
    4392              : {
    4393        14417 :   return get_kind () == other.get_kind ();
    4394              : }
    4395              : 
    4396              : // Never Type
    4397              : 
    4398         6222 : NeverType::NeverType (HirId ref, std::set<HirId> refs)
    4399              :   : BaseType (ref, ref, KIND,
    4400         6222 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4401        12444 :               refs)
    4402         6222 : {}
    4403              : 
    4404          797 : NeverType::NeverType (HirId ref, HirId ty_ref, std::set<HirId> refs)
    4405              :   : BaseType (ref, ty_ref, KIND,
    4406          797 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4407         1594 :               refs)
    4408          797 : {}
    4409              : 
    4410              : std::string
    4411           96 : NeverType::get_name () const
    4412              : {
    4413           96 :   return as_string ();
    4414              : }
    4415              : 
    4416              : void
    4417            0 : NeverType::accept_vis (TyVisitor &vis)
    4418              : {
    4419            0 :   vis.visit (*this);
    4420            0 : }
    4421              : 
    4422              : void
    4423         5018 : NeverType::accept_vis (TyConstVisitor &vis) const
    4424              : {
    4425         5018 :   vis.visit (*this);
    4426         5018 : }
    4427              : 
    4428              : std::string
    4429         1592 : NeverType::as_string () const
    4430              : {
    4431         1592 :   return "!";
    4432              : }
    4433              : 
    4434              : BaseType *
    4435          797 : NeverType::clone () const
    4436              : {
    4437          797 :   return new NeverType (get_ref (), get_ty_ref (), get_combined_refs ());
    4438              : }
    4439              : 
    4440              : // placeholder type
    4441              : 
    4442            0 : PlaceholderType::PlaceholderType (std::string symbol, DefId id, HirId ref,
    4443              :                                   std::set<HirId> refs)
    4444              :   : BaseType (ref, ref, KIND,
    4445            0 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4446              :               refs),
    4447            0 :     symbol (symbol), defId (id)
    4448            0 : {}
    4449              : 
    4450            0 : PlaceholderType::PlaceholderType (std::string symbol, DefId id, HirId ref,
    4451              :                                   HirId ty_ref, std::set<HirId> refs)
    4452              :   : BaseType (ref, ty_ref, KIND,
    4453            0 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4454              :               refs),
    4455            0 :     symbol (symbol), defId (id)
    4456            0 : {}
    4457              : 
    4458              : std::string
    4459            0 : PlaceholderType::get_name () const
    4460              : {
    4461            0 :   return as_string ();
    4462              : }
    4463              : 
    4464              : std::string
    4465            0 : PlaceholderType::get_symbol () const
    4466              : {
    4467            0 :   return symbol;
    4468              : }
    4469              : 
    4470              : void
    4471            0 : PlaceholderType::accept_vis (TyVisitor &vis)
    4472              : {
    4473            0 :   vis.visit (*this);
    4474            0 : }
    4475              : 
    4476              : void
    4477            0 : PlaceholderType::accept_vis (TyConstVisitor &vis) const
    4478              : {
    4479            0 :   vis.visit (*this);
    4480            0 : }
    4481              : 
    4482              : std::string
    4483            0 : PlaceholderType::as_string () const
    4484              : {
    4485            0 :   return "<placeholder:" + (can_resolve () ? resolve ()->as_string () : "")
    4486            0 :          + ">";
    4487              : }
    4488              : 
    4489              : BaseType *
    4490            0 : PlaceholderType::clone () const
    4491              : {
    4492            0 :   return new PlaceholderType (get_symbol (), get_def_id (), get_ref (),
    4493            0 :                               get_ty_ref (), get_combined_refs ());
    4494              : }
    4495              : 
    4496              : bool
    4497            0 : PlaceholderType::can_resolve () const
    4498              : {
    4499            0 :   auto context = Resolver::TypeCheckContext::get ();
    4500              : 
    4501            0 :   BaseType *lookup = nullptr;
    4502            0 :   HirId mapping;
    4503              : 
    4504            0 :   if (!context->lookup_associated_type_mapping (get_ty_ref (), &mapping))
    4505              :     return false;
    4506              : 
    4507            0 :   if (!context->lookup_type (mapping, &lookup))
    4508              :     return false;
    4509              : 
    4510            0 :   return lookup != nullptr;
    4511              : }
    4512              : 
    4513              : BaseType *
    4514            0 : PlaceholderType::resolve () const
    4515              : {
    4516            0 :   auto context = Resolver::TypeCheckContext::get ();
    4517              : 
    4518            0 :   HirId mapping;
    4519            0 :   bool ok = context->lookup_associated_type_mapping (get_ty_ref (), &mapping);
    4520            0 :   rust_assert (ok);
    4521              : 
    4522            0 :   return TyVar (mapping).get_tyty ();
    4523              : }
    4524              : 
    4525              : bool
    4526            0 : PlaceholderType::is_equal (const BaseType &other) const
    4527              : {
    4528            0 :   if (get_kind () != other.get_kind ())
    4529              :     {
    4530            0 :       if (!can_resolve ())
    4531              :         return false;
    4532              : 
    4533            0 :       return resolve ()->is_equal (other);
    4534              :     }
    4535              : 
    4536            0 :   auto other2 = static_cast<const PlaceholderType &> (other);
    4537            0 :   return get_symbol ().compare (other2.get_symbol ()) == 0;
    4538            0 : }
    4539              : 
    4540              : DefId
    4541            0 : PlaceholderType::get_def_id () const
    4542              : {
    4543            0 :   return defId;
    4544              : }
    4545              : 
    4546              : // Projection type
    4547              : 
    4548         2981 : ProjectionType::ProjectionType (
    4549              :   HirId ref, BaseType *base, const Resolver::TraitReference *trait, DefId item,
    4550              :   std::vector<SubstitutionParamMapping> subst_refs, TyTy::BaseType *self,
    4551              :   SubstitutionArgumentMappings generic_arguments,
    4552              :   RegionConstraints region_constraints, std::set<HirId> refs,
    4553              :   size_t num_trait_substitutions)
    4554              :   : BaseType (ref, ref, KIND,
    4555         2981 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4556              :               std::move (refs)),
    4557              :     SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
    4558              :                      std::move (region_constraints)),
    4559         2981 :     base (base), trait (trait), item (item), self (self),
    4560         5962 :     num_trait_substitutions (num_trait_substitutions)
    4561         2981 : {}
    4562              : 
    4563        13323 : ProjectionType::ProjectionType (
    4564              :   HirId ref, HirId ty_ref, BaseType *base,
    4565              :   const Resolver::TraitReference *trait, DefId item,
    4566              :   std::vector<SubstitutionParamMapping> subst_refs, TyTy::BaseType *self,
    4567              :   SubstitutionArgumentMappings generic_arguments,
    4568              :   RegionConstraints region_constraints, std::set<HirId> refs,
    4569              :   size_t num_trait_substitutions)
    4570              :   : BaseType (ref, ty_ref, KIND,
    4571        13323 :               {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
    4572              :               refs),
    4573              :     SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
    4574              :                      std::move (region_constraints)),
    4575        13323 :     base (base), trait (trait), item (item), self (self),
    4576        26646 :     num_trait_substitutions (num_trait_substitutions)
    4577        13323 : {}
    4578              : 
    4579              : std::string
    4580           53 : ProjectionType::get_name () const
    4581              : {
    4582           53 :   return as_string ();
    4583              : }
    4584              : 
    4585              : bool
    4586        21382 : ProjectionType::is_trait_position () const
    4587              : {
    4588        21382 :   return base == nullptr;
    4589              : }
    4590              : 
    4591              : const BaseType *
    4592            0 : ProjectionType::get () const
    4593              : {
    4594            0 :   rust_assert (base != nullptr);
    4595            0 :   return base;
    4596              : }
    4597              : 
    4598              : BaseType *
    4599        10321 : ProjectionType::get ()
    4600              : {
    4601        10321 :   rust_assert (base != nullptr);
    4602        10321 :   return base;
    4603              : }
    4604              : 
    4605              : const BaseType *
    4606         9443 : ProjectionType::get_self () const
    4607              : {
    4608         9443 :   return self;
    4609              : }
    4610              : 
    4611              : BaseType *
    4612        14621 : ProjectionType::get_self ()
    4613              : {
    4614        14621 :   return self;
    4615              : }
    4616              : 
    4617              : const Resolver::TraitReference *
    4618        16155 : ProjectionType::get_trait_ref () const
    4619              : {
    4620        16155 :   return trait;
    4621              : }
    4622              : 
    4623              : DefId
    4624         9120 : ProjectionType::get_item_defid () const
    4625              : {
    4626         9120 :   return item;
    4627              : }
    4628              : 
    4629              : void
    4630         6163 : ProjectionType::accept_vis (TyVisitor &vis)
    4631              : {
    4632         6163 :   vis.visit (*this);
    4633         6163 : }
    4634              : 
    4635              : void
    4636          378 : ProjectionType::accept_vis (TyConstVisitor &vis) const
    4637              : {
    4638          378 :   vis.visit (*this);
    4639          378 : }
    4640              : 
    4641              : std::string
    4642          327 : ProjectionType::as_string () const
    4643              : {
    4644          654 :   return "<Projection=" + subst_as_string ()
    4645         1308 :          + "::" + (base == nullptr ? "TRAIT_POSITION" : base->as_string ())
    4646         1308 :          + "::" + self->as_string () + ">";
    4647              : }
    4648              : 
    4649              : BaseType *
    4650        10822 : ProjectionType::clone () const
    4651              : {
    4652        10822 :   auto *cloned
    4653              :     = new ProjectionType (get_ref (), get_ty_ref (),
    4654         1276 :                           base != nullptr ? base->clone () : nullptr, trait,
    4655        10822 :                           item, clone_substs (), self->clone (), used_arguments,
    4656        32466 :                           region_constraints, get_combined_refs (),
    4657        33742 :                           num_trait_substitutions);
    4658        10822 :   cloned->inherit_bounds (get_specified_bounds ());
    4659        10822 :   return cloned;
    4660              : }
    4661              : 
    4662              : ProjectionType *
    4663         6159 : ProjectionType::handle_substitions (
    4664              :   SubstitutionArgumentMappings &subst_mappings)
    4665              : {
    4666         6159 :   ProjectionType *projection = static_cast<ProjectionType *> (clone ());
    4667         6159 :   projection->set_ty_ref (mappings.get_next_hir_id ());
    4668         6159 :   projection->used_arguments = subst_mappings;
    4669              : 
    4670         6159 :   auto context = Resolver::TypeCheckContext::get ();
    4671         6159 :   context->insert_implicit_type (projection->get_ty_ref (), projection);
    4672              : 
    4673        15265 :   for (auto &sub : projection->get_substs ())
    4674              :     {
    4675         9106 :       SubstitutionArg arg = SubstitutionArg::error ();
    4676         9106 :       bool ok
    4677         9106 :         = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg);
    4678         9106 :       if (ok)
    4679         8668 :         sub.fill_param_ty (subst_mappings, subst_mappings.get_locus ());
    4680              :     }
    4681              : 
    4682         6159 :   auto fty = projection->self;
    4683         6159 :   if (fty->get_kind () == TypeKind::PARAM)
    4684              :     {
    4685         5060 :       ParamType *p = static_cast<ParamType *> (fty);
    4686              : 
    4687         5060 :       SubstitutionArg arg = SubstitutionArg::error ();
    4688         5060 :       bool ok = subst_mappings.get_argument_for_symbol (p, &arg);
    4689         5060 :       if (ok)
    4690              :         {
    4691         4837 :           auto argt = arg.get_tyty ();
    4692         4837 :           bool arg_is_param = argt->get_kind () == TyTy::TypeKind::PARAM;
    4693         4837 :           bool arg_is_concrete = argt->get_kind () != TyTy::TypeKind::INFER;
    4694              : 
    4695         4837 :           if (arg_is_param || arg_is_concrete)
    4696              :             {
    4697         4484 :               auto new_field = argt->clone ();
    4698         4484 :               new_field->set_ref (fty->get_ref ());
    4699         4484 :               projection->self = new_field;
    4700              :             }
    4701              :           else
    4702              :             {
    4703          353 :               fty->set_ty_ref (argt->get_ref ());
    4704              :             }
    4705              :         }
    4706              :     }
    4707         1099 :   else if (fty->needs_generic_substitutions () || !fty->is_concrete ())
    4708              :     {
    4709          186 :       BaseType *concrete
    4710          186 :         = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings);
    4711              : 
    4712          186 :       if (concrete == nullptr || concrete->get_kind () == TyTy::TypeKind::ERROR)
    4713              :         {
    4714            0 :           rust_error_at (subst_mappings.get_locus (),
    4715              :                          "Failed to resolve field substitution type: %s",
    4716            0 :                          fty->as_string ().c_str ());
    4717            0 :           return nullptr;
    4718              :         }
    4719              : 
    4720          186 :       projection->self = concrete;
    4721              :     }
    4722              : 
    4723         6159 :   fty = projection->base;
    4724         6159 :   if (fty == nullptr)
    4725              :     return projection;
    4726              : 
    4727         1241 :   if (fty->get_kind () == TypeKind::PARAM)
    4728              :     {
    4729          613 :       ParamType *p = static_cast<ParamType *> (fty);
    4730              : 
    4731          613 :       SubstitutionArg arg = SubstitutionArg::error ();
    4732          613 :       bool ok = subst_mappings.get_argument_for_symbol (p, &arg);
    4733          613 :       if (ok)
    4734              :         {
    4735          407 :           auto argt = arg.get_tyty ();
    4736          407 :           bool arg_is_param = argt->get_kind () == TyTy::TypeKind::PARAM;
    4737          407 :           bool arg_is_concrete = argt->get_kind () != TyTy::TypeKind::INFER;
    4738              : 
    4739          407 :           if (arg_is_param || arg_is_concrete)
    4740              :             {
    4741          390 :               auto new_field = argt->clone ();
    4742          390 :               new_field->set_ref (fty->get_ref ());
    4743          390 :               projection->base = new_field;
    4744              :             }
    4745              :           else
    4746              :             {
    4747           17 :               fty->set_ty_ref (argt->get_ref ());
    4748              :             }
    4749              :         }
    4750              :     }
    4751          628 :   else if (fty->needs_generic_substitutions () || !fty->is_concrete ())
    4752              :     {
    4753          140 :       BaseType *concrete
    4754          140 :         = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings);
    4755              : 
    4756          140 :       if (concrete == nullptr || concrete->get_kind () == TyTy::TypeKind::ERROR)
    4757              :         {
    4758            0 :           rust_error_at (subst_mappings.get_locus (),
    4759              :                          "Failed to resolve field substitution type: %s",
    4760            0 :                          fty->as_string ().c_str ());
    4761            0 :           return nullptr;
    4762              :         }
    4763              : 
    4764          140 :       projection->base = concrete;
    4765              :     }
    4766              : 
    4767              :   return projection;
    4768              : }
    4769              : 
    4770              : // DynObjectType
    4771              : 
    4772         4784 : DynamicObjectType::DynamicObjectType (
    4773              :   HirId ref, RustIdent ident, std::vector<TypeBoundPredicate> specified_bounds,
    4774              :   std::set<HirId> refs)
    4775         4784 :   : BaseType (ref, ref, KIND, ident, specified_bounds, refs)
    4776         4784 : {}
    4777              : 
    4778          738 : DynamicObjectType::DynamicObjectType (
    4779              :   HirId ref, HirId ty_ref, RustIdent ident,
    4780              :   std::vector<TypeBoundPredicate> specified_bounds, std::set<HirId> refs)
    4781          738 :   : BaseType (ref, ty_ref, KIND, ident, specified_bounds, refs)
    4782          738 : {}
    4783              : 
    4784              : void
    4785            3 : DynamicObjectType::accept_vis (TyVisitor &vis)
    4786              : {
    4787            3 :   vis.visit (*this);
    4788            3 : }
    4789              : 
    4790              : void
    4791          198 : DynamicObjectType::accept_vis (TyConstVisitor &vis) const
    4792              : {
    4793          198 :   vis.visit (*this);
    4794          198 : }
    4795              : 
    4796              : std::string
    4797          171 : DynamicObjectType::as_string () const
    4798              : {
    4799          342 :   return "dyn [" + raw_bounds_as_string () + "]";
    4800              : }
    4801              : 
    4802              : BaseType *
    4803          738 : DynamicObjectType::clone () const
    4804              : {
    4805          738 :   return new DynamicObjectType (get_ref (), get_ty_ref (), ident,
    4806         1476 :                                 specified_bounds, get_combined_refs ());
    4807              : }
    4808              : 
    4809              : std::string
    4810          812 : DynamicObjectType::get_name () const
    4811              : {
    4812         1624 :   return "dyn [" + raw_bounds_as_name () + "]";
    4813              : }
    4814              : 
    4815              : bool
    4816         4577 : DynamicObjectType::is_equal (const BaseType &other) const
    4817              : {
    4818         4577 :   if (get_kind () != other.get_kind ())
    4819              :     return false;
    4820              : 
    4821         1398 :   if (num_specified_bounds () != other.num_specified_bounds ())
    4822              :     return false;
    4823              : 
    4824         2804 :   for (const auto &pred : specified_bounds)
    4825              :     {
    4826         1406 :       bool found = false;
    4827         1424 :       for (const auto &opred : other.get_specified_bounds ())
    4828              :         {
    4829         1424 :           found = pred.is_equal (opred);
    4830         1424 :           if (found)
    4831              :             break;
    4832              :         }
    4833              : 
    4834         1406 :       if (!found)
    4835         4577 :         return false;
    4836              :     }
    4837              : 
    4838              :   return true;
    4839              : }
    4840              : 
    4841              : const std::vector<
    4842              :   std::pair<const Resolver::TraitItemReference *, const TypeBoundPredicate *>>
    4843         1119 : DynamicObjectType::get_object_items () const
    4844              : {
    4845         1119 :   std::vector<
    4846              :     std::pair<const Resolver::TraitItemReference *, const TypeBoundPredicate *>>
    4847         1119 :     items;
    4848         2250 :   for (const TypeBoundPredicate &bound : get_specified_bounds ())
    4849              :     {
    4850         1131 :       const Resolver::TraitReference *trait = bound.get ();
    4851         1131 :       std::vector<const Resolver::TraitItemReference *> trait_items;
    4852         1131 :       trait->get_trait_items_and_supers (trait_items);
    4853              : 
    4854         2702 :       for (auto &item : trait_items)
    4855              :         {
    4856         1571 :           if (item->get_trait_item_type ()
    4857              :                 == Resolver::TraitItemReference::TraitItemType::FN
    4858         1571 :               && item->is_object_safe ())
    4859         1571 :             items.emplace_back (item, &bound);
    4860              :         }
    4861         1131 :     }
    4862         1119 :   return items;
    4863              : }
    4864              : 
    4865              : WARN_UNUSED_RESULT tl::optional<BaseType *>
    4866        30524 : try_get_box_inner_type (BaseType *base)
    4867              : {
    4868        30524 :   if (base->get_kind () != TypeKind::ADT)
    4869        21413 :     return tl::nullopt;
    4870              : 
    4871         9111 :   ADTType *adt = static_cast<ADTType *> (base);
    4872         9111 :   auto owned_box_lookup
    4873         9111 :     = Analysis::Mappings::get ().lookup_lang_item (LangItem::Kind::OWNED_BOX);
    4874              : 
    4875         9116 :   if (owned_box_lookup && adt->get_id () == *owned_box_lookup)
    4876              :     {
    4877           43 :       auto args = adt->get_substitution_arguments ();
    4878           43 :       if (!args.is_empty ())
    4879              :         {
    4880           43 :           auto inner = args.get_mappings ().front ().get_tyty ();
    4881           43 :           rust_assert (inner != nullptr);
    4882           43 :           return inner;
    4883              :         }
    4884           43 :     }
    4885         9068 :   return tl::nullopt;
    4886              : }
    4887              : 
    4888              : } // namespace TyTy
    4889              : } // 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.