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

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