LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-unify.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 83.5 % 1403 1172
Test Date: 2026-02-28 14:20:25 Functions: 88.6 % 35 31
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-unify.h"
      20              : #include "fold-const.h"
      21              : #include "rust-tyty-util.h"
      22              : #include "rust-tyty.h"
      23              : 
      24              : namespace Rust {
      25              : namespace Resolver {
      26              : 
      27              : static TyTy::BaseType *
      28      1589163 : unify_error_type_node ()
      29              : {
      30      1589163 :   static TyTy::BaseType *error = nullptr;
      31      1589163 :   if (error == nullptr)
      32         1056 :     error = new TyTy::ErrorType (0);
      33      1589163 :   return error;
      34              : }
      35              : 
      36      2213200 : UnifyRules::UnifyRules (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
      37              :                         location_t locus, bool commit_flag, bool emit_error,
      38              :                         bool check_bounds, bool infer,
      39              :                         std::vector<CommitSite> &commits,
      40      2213200 :                         std::vector<InferenceSite> &infers)
      41      2213200 :   : lhs (lhs), rhs (rhs), locus (locus), commit_flag (commit_flag),
      42      2213200 :     emit_error (emit_error), infer_flag (infer),
      43      2213200 :     check_bounds_flag (check_bounds), commits (commits), infers (infers),
      44      2213200 :     mappings (Analysis::Mappings::get ()), context (*TypeCheckContext::get ())
      45      2213200 : {}
      46              : 
      47              : TyTy::BaseType *
      48      2213200 : UnifyRules::Resolve (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
      49              :                      location_t locus, bool commit_flag, bool emit_error,
      50              :                      bool check_bounds, bool infer,
      51              :                      std::vector<CommitSite> &commits,
      52              :                      std::vector<InferenceSite> &infers)
      53              : {
      54      2213200 :   UnifyRules r (lhs, rhs, locus, commit_flag, emit_error, infer, check_bounds,
      55      2213200 :                 commits, infers);
      56              : 
      57      2213200 :   TyTy::BaseType *result = r.go ();
      58      2213200 :   bool failed = result->get_kind () == TyTy::TypeKind::ERROR;
      59              : 
      60      2213200 :   commits.emplace_back (lhs.get_ty (), rhs.get_ty (), result);
      61      2213200 :   if (r.commit_flag && !failed)
      62              :     {
      63        47091 :       result = result->clone ();
      64        47091 :       UnifyRules::commit (lhs.get_ty (), rhs.get_ty (), result);
      65              :     }
      66              : 
      67      2213200 :   if (failed && r.emit_error)
      68           68 :     r.emit_type_mismatch ();
      69              : 
      70      2213200 :   return result;
      71              : }
      72              : 
      73              : TyTy::BaseType *
      74       175351 : UnifyRules::resolve_subtype (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs)
      75              : {
      76       175351 :   TyTy::BaseType *result
      77       350702 :     = UnifyRules::Resolve (lhs, rhs, locus, commit_flag, emit_error, infer_flag,
      78       175351 :                            check_bounds_flag, commits, infers);
      79              : 
      80              :   // If the recursive call resulted in an error and would have emitted an error
      81              :   // message, disable error emission for the current level to avoid duplicate
      82              :   // errors
      83       175351 :   if (result->get_kind () == TyTy::TypeKind::ERROR && emit_error)
      84           13 :     emit_error = false;
      85              : 
      86       175351 :   return result;
      87              : }
      88              : 
      89              : TyTy::BaseType *
      90            0 : UnifyRules::get_base ()
      91              : {
      92            0 :   return lhs.get_ty ()->destructure ();
      93              : }
      94              : 
      95              : TyTy::BaseType *
      96            0 : UnifyRules::get_other ()
      97              : {
      98            0 :   return rhs.get_ty ()->destructure ();
      99              : }
     100              : 
     101              : void
     102       162594 : UnifyRules::commit (TyTy::BaseType *base, TyTy::BaseType *other,
     103              :                     TyTy::BaseType *resolved)
     104              : {
     105       162594 :   TypeCheckContext &context = *TypeCheckContext::get ();
     106              : 
     107       162594 :   TyTy::BaseType *b = base->destructure ();
     108       162594 :   TyTy::BaseType *o = other->destructure ();
     109              : 
     110       162594 :   resolved->append_reference (b->get_ref ());
     111       162594 :   resolved->append_reference (o->get_ref ());
     112      1187143 :   for (auto ref : b->get_combined_refs ())
     113      1024549 :     resolved->append_reference (ref);
     114      1150181 :   for (auto ref : o->get_combined_refs ())
     115       987587 :     resolved->append_reference (ref);
     116              : 
     117       162594 :   o->append_reference (resolved->get_ref ());
     118       162594 :   o->append_reference (b->get_ref ());
     119       162594 :   b->append_reference (resolved->get_ref ());
     120       162594 :   b->append_reference (o->get_ref ());
     121              : 
     122       162594 :   if (resolved->get_kind () != TyTy::TypeKind::CONST)
     123              :     {
     124       161040 :       bool result_resolved = resolved->get_kind () != TyTy::TypeKind::INFER;
     125       161040 :       bool result_is_infer_var = resolved->get_kind () == TyTy::TypeKind::INFER;
     126       161040 :       bool results_is_non_general_infer_var
     127              :         = (result_is_infer_var
     128       161040 :            && (static_cast<TyTy::InferType *> (resolved))->get_infer_kind ()
     129       316743 :                 != TyTy::InferType::GENERAL);
     130       155883 :       if (result_resolved || results_is_non_general_infer_var)
     131              :         {
     132      1492228 :           for (auto &ref : resolved->get_combined_refs ())
     133              :             {
     134      1331368 :               TyTy::BaseType *ref_tyty = nullptr;
     135      1331368 :               bool ok = context.lookup_type (ref, &ref_tyty);
     136      1331368 :               if (!ok)
     137         3446 :                 continue;
     138              : 
     139              :               // if any of the types are inference variables lets fix them
     140      1327922 :               if (ref_tyty->is<TyTy::InferType> ())
     141        75335 :                 context.insert_implicit_type (ref, resolved);
     142       160860 :             }
     143              :         }
     144              :     }
     145              :   else
     146              :     {
     147         1554 :       auto base_const = resolved->as_const_type ();
     148         1554 :       if (base_const->const_kind () == TyTy::BaseConstType::ConstKind::Value)
     149              :         {
     150         1533 :           rust_debug ("UnifyRules::commit const value, resolved_ref=%u "
     151              :                       "resolved_ty_ref=%u combined_refs.size=%zu",
     152              :                       resolved->get_ref (), resolved->get_ty_ref (),
     153              :                       resolved->get_combined_refs ().size ());
     154              : 
     155         4524 :           for (auto &ref : resolved->get_combined_refs ())
     156              :             {
     157         2991 :               TyTy::BaseType *ref_tyty = nullptr;
     158         2991 :               bool ok = context.lookup_type (ref, &ref_tyty);
     159         2991 :               if (!ok)
     160            0 :                 continue;
     161         2991 :               if (ref_tyty->get_kind () != TyTy::TypeKind::CONST)
     162            0 :                 continue;
     163              : 
     164         2991 :               auto ref_base_const = ref_tyty->as_const_type ();
     165         2991 :               if (ref_base_const->const_kind ()
     166              :                     == TyTy::BaseConstType::ConstKind::Infer
     167         2991 :                   || ref_base_const->const_kind ()
     168              :                        == TyTy::BaseConstType::ConstKind::Decl)
     169              :                 {
     170           56 :                   rust_debug ("  committing to ref=%u kind=%d", ref,
     171              :                               (int) ref_base_const->const_kind ());
     172           56 :                   context.insert_implicit_type (ref, resolved);
     173              :                 }
     174         1533 :             }
     175              :         }
     176              :     }
     177       162594 : }
     178              : 
     179              : void
     180           68 : UnifyRules::emit_type_mismatch () const
     181              : {
     182           68 :   TyTy::BaseType *expected = lhs.get_ty ();
     183           68 :   TyTy::BaseType *expr = rhs.get_ty ();
     184              : 
     185           68 :   rich_location r (line_table, locus);
     186           68 :   r.add_range (lhs.get_locus ());
     187           68 :   r.add_range (rhs.get_locus ());
     188           68 :   rust_error_at (r, ErrorCode::E0308,
     189              :                  "mismatched types, expected %qs but got %qs",
     190          136 :                  expected->get_name ().c_str (), expr->get_name ().c_str ());
     191           68 : }
     192              : 
     193              : void
     194            0 : UnifyRules::emit_abi_mismatch (const TyTy::FnType &expected,
     195              :                                const TyTy::FnType &got) const
     196              : {
     197            0 :   rich_location r (line_table, locus);
     198            0 :   r.add_range (lhs.get_locus ());
     199            0 :   r.add_range (rhs.get_locus ());
     200            0 :   rust_error_at (r, "mistached abi %qs got %qs",
     201            0 :                  get_string_from_abi (expected.get_abi ()).c_str (),
     202            0 :                  get_string_from_abi (got.get_abi ()).c_str ());
     203            0 : }
     204              : 
     205              : TyTy::BaseType *
     206      2213200 : UnifyRules::go ()
     207              : {
     208      2213200 :   TyTy::BaseType *ltype = lhs.get_ty ()->destructure ();
     209      2213200 :   TyTy::BaseType *rtype = rhs.get_ty ()->destructure ();
     210              : 
     211      2213200 :   rust_debug ("unify::go ltype={%s} rtype={%s}", ltype->debug_str ().c_str (),
     212              :               rtype->debug_str ().c_str ());
     213              : 
     214      2213200 :   if (check_bounds_flag)
     215              :     {
     216       318631 :       bool ltype_is_placeholder
     217       318631 :         = ltype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
     218       318631 :       bool rtype_is_placeholder
     219       318631 :         = rtype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
     220       318631 :       bool types_equal = ltype->is_equal (*rtype);
     221      2655228 :       bool should_check_bounds
     222       318631 :         = !types_equal && !(ltype_is_placeholder || rtype_is_placeholder);
     223       130226 :       if (should_check_bounds)
     224              :         {
     225       130226 :           if (ltype->num_specified_bounds () > 0)
     226              :             {
     227        31266 :               if (!ltype->bounds_compatible (*rtype, locus, emit_error))
     228              :                 {
     229              :                   // already emitted an error
     230         2811 :                   emit_error = false;
     231         2811 :                   return unify_error_type_node ();
     232              :                 }
     233              :             }
     234        98960 :           else if (rtype->num_specified_bounds () > 0)
     235              :             {
     236        23561 :               if (!rtype->bounds_compatible (*ltype, locus, emit_error))
     237              :                 {
     238              :                   // already emitted an error
     239         4018 :                   emit_error = false;
     240         4018 :                   return unify_error_type_node ();
     241              :                 }
     242              :             }
     243              :         }
     244              :     }
     245              : 
     246      2206371 :   if (infer_flag)
     247              :     {
     248      2099077 :       bool rgot_param = rtype->get_kind () == TyTy::TypeKind::PARAM;
     249      2099077 :       bool lhs_is_infer_var = ltype->get_kind () == TyTy::TypeKind::INFER;
     250      2099077 :       bool lhs_is_general_infer_var
     251              :         = lhs_is_infer_var
     252      2099077 :           && static_cast<TyTy::InferType *> (ltype)->get_infer_kind ()
     253      2099077 :                == TyTy::InferType::GENERAL;
     254      2099077 :       bool expected_is_concrete
     255      2099077 :         = ltype->is_concrete () && !lhs_is_general_infer_var;
     256      2099077 :       bool rneeds_infer = expected_is_concrete && (rgot_param);
     257              : 
     258      2099077 :       bool lgot_param = ltype->get_kind () == TyTy::TypeKind::PARAM;
     259      2099077 :       bool rhs_is_infer_var = rtype->get_kind () == TyTy::TypeKind::INFER;
     260      2099077 :       bool rhs_is_general_infer_var
     261              :         = rhs_is_infer_var
     262      2099077 :           && static_cast<TyTy::InferType *> (rtype)->get_infer_kind ()
     263      2099077 :                == TyTy::InferType::GENERAL;
     264      2099077 :       bool receiver_is_concrete
     265      2099077 :         = rtype->is_concrete () && !rhs_is_general_infer_var;
     266      2099077 :       bool lneeds_infer = receiver_is_concrete && (lgot_param);
     267              : 
     268      2099077 :       if (rneeds_infer)
     269              :         {
     270        72462 :           TyTy::ParamType *p = static_cast<TyTy::ParamType *> (rtype);
     271        72462 :           TyTy::TyVar iv
     272        72462 :             = TyTy::TyVar::get_implicit_infer_var (rhs.get_locus ());
     273        72462 :           rust_assert (iv.get_tyty ()->get_kind () == TyTy::TypeKind::INFER);
     274        72462 :           TyTy::InferType *i = static_cast<TyTy::InferType *> (iv.get_tyty ());
     275              : 
     276        72462 :           infers.emplace_back (p->get_ref (), p->get_ty_ref (), p, i);
     277              : 
     278              :           // FIXME
     279              :           // this is hacky to set the implicit param lets make this a function
     280        72462 :           p->set_ty_ref (i->get_ref ());
     281              : 
     282              :           // set the rtype now to the new inference var
     283        72462 :           rtype = i;
     284              :         }
     285      2026615 :       else if (lneeds_infer)
     286              :         {
     287        12447 :           TyTy::ParamType *p = static_cast<TyTy::ParamType *> (ltype);
     288        12447 :           TyTy::TyVar iv
     289        12447 :             = TyTy::TyVar::get_implicit_infer_var (lhs.get_locus ());
     290        12447 :           rust_assert (iv.get_tyty ()->get_kind () == TyTy::TypeKind::INFER);
     291        12447 :           TyTy::InferType *i = static_cast<TyTy::InferType *> (iv.get_tyty ());
     292              : 
     293        12447 :           infers.emplace_back (p->get_ref (), p->get_ty_ref (), p, i);
     294              : 
     295              :           // FIXME
     296              :           // this is hacky to set the implicit param lets make this a function
     297        12447 :           p->set_ty_ref (i->get_ref ());
     298              : 
     299              :           // set the rtype now to the new inference var
     300        12447 :           ltype = i;
     301              :         }
     302      2014168 :       else if (ltype->get_kind () == TyTy::TypeKind::CONST
     303      2014168 :                && rtype->get_kind () == TyTy::TypeKind::CONST)
     304              :         {
     305         1007 :           auto lhs = ltype->as_const_type ();
     306         1007 :           auto rhs = rtype->as_const_type ();
     307              : 
     308         1007 :           bool both_are_decls
     309         1007 :             = lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl
     310         1007 :               && rhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl;
     311         1007 :           bool have_decls
     312         1007 :             = lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl
     313         1007 :               || rhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl;
     314              : 
     315         1007 :           if (have_decls && !both_are_decls)
     316              :             {
     317           49 :               if (lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl)
     318              :                 {
     319            7 :                   auto l = lhs->as_base_type ()->get_locus ();
     320            7 :                   auto p = static_cast<TyTy::ConstParamType *> (lhs);
     321            7 :                   auto it = TyTy::TyVar::get_implicit_infer_var (l);
     322            7 :                   auto iv = TyTy::TyVar::get_implicit_const_infer_var (l, &it);
     323            7 :                   auto ivt = iv.get_tyty ();
     324              : 
     325            7 :                   infers.emplace_back (0, 0, nullptr, it.get_tyty ());
     326            7 :                   infers.emplace_back (ltype->get_ref (), ltype->get_ty_ref (),
     327              :                                        p, ivt);
     328              : 
     329            7 :                   ltype = ivt;
     330            7 :                   p->set_ty_ref (ltype->get_ref ());
     331              :                 }
     332           42 :               else if (rhs->const_kind ()
     333              :                        == TyTy::BaseConstType::ConstKind::Decl)
     334              :                 {
     335           42 :                   auto l = rhs->as_base_type ()->get_locus ();
     336           42 :                   auto p = static_cast<TyTy::ConstParamType *> (rhs);
     337           42 :                   auto it = TyTy::TyVar::get_implicit_infer_var (l);
     338           42 :                   auto iv = TyTy::TyVar::get_implicit_const_infer_var (l, &it);
     339           42 :                   auto ivt = iv.get_tyty ();
     340              : 
     341           42 :                   infers.emplace_back (0, 0, nullptr, it.get_tyty ());
     342           42 :                   infers.emplace_back (rtype->get_ref (), rtype->get_ty_ref (),
     343              :                                        p, ivt);
     344              : 
     345           42 :                   rtype = ivt;
     346           42 :                   p->set_ty_ref (rtype->get_ref ());
     347              :                 }
     348              :             }
     349              :         }
     350              :     }
     351              : 
     352      2206371 :   if (ltype->get_kind () != TyTy::TypeKind::CONST
     353      2206371 :       && rtype->get_kind () == TyTy::TypeKind::CONST)
     354              :     {
     355           28 :       auto *rc = rtype->as_const_type ();
     356           28 :       rtype = rc->get_specified_type ();
     357              :     }
     358              : 
     359      2206371 :   if (ltype->get_kind () == TyTy::TypeKind::CONST
     360      2206371 :       && rtype->get_kind () != TyTy::TypeKind::CONST)
     361              :     {
     362            0 :       auto *lc = ltype->as_const_type ();
     363            0 :       ltype = lc->get_specified_type ();
     364              :     }
     365              : 
     366      2206371 :   switch (ltype->get_kind ())
     367              :     {
     368        46940 :     case TyTy::INFER:
     369        46940 :       return expect_inference_variable (static_cast<TyTy::InferType *> (ltype),
     370        46940 :                                         rtype);
     371              : 
     372       232494 :     case TyTy::ADT:
     373       232494 :       return expect_adt (static_cast<TyTy::ADTType *> (ltype), rtype);
     374              : 
     375         6982 :     case TyTy::STR:
     376         6982 :       return expect_str (static_cast<TyTy::StrType *> (ltype), rtype);
     377              : 
     378        64719 :     case TyTy::REF:
     379        64719 :       return expect_reference (static_cast<TyTy::ReferenceType *> (ltype),
     380        64719 :                                rtype);
     381              : 
     382        20403 :     case TyTy::POINTER:
     383        20403 :       return expect_pointer (static_cast<TyTy::PointerType *> (ltype), rtype);
     384              : 
     385        19824 :     case TyTy::PARAM:
     386        19824 :       return expect_param (static_cast<TyTy::ParamType *> (ltype), rtype);
     387              : 
     388        13438 :     case TyTy::ARRAY:
     389        13438 :       return expect_array (static_cast<TyTy::ArrayType *> (ltype), rtype);
     390              : 
     391         4314 :     case TyTy::SLICE:
     392         4314 :       return expect_slice (static_cast<TyTy::SliceType *> (ltype), rtype);
     393              : 
     394         4331 :     case TyTy::FNDEF:
     395         4331 :       return expect_fndef (static_cast<TyTy::FnType *> (ltype), rtype);
     396              : 
     397          336 :     case TyTy::FNPTR:
     398          336 :       return expect_fnptr (static_cast<TyTy::FnPtr *> (ltype), rtype);
     399              : 
     400        12072 :     case TyTy::TUPLE:
     401        12072 :       return expect_tuple (static_cast<TyTy::TupleType *> (ltype), rtype);
     402              : 
     403        19958 :     case TyTy::BOOL:
     404        19958 :       return expect_bool (static_cast<TyTy::BoolType *> (ltype), rtype);
     405              : 
     406         9791 :     case TyTy::CHAR:
     407         9791 :       return expect_char (static_cast<TyTy::CharType *> (ltype), rtype);
     408              : 
     409       305498 :     case TyTy::INT:
     410       305498 :       return expect_int (static_cast<TyTy::IntType *> (ltype), rtype);
     411              : 
     412       885026 :     case TyTy::UINT:
     413       885026 :       return expect_uint (static_cast<TyTy::UintType *> (ltype), rtype);
     414              : 
     415        65144 :     case TyTy::FLOAT:
     416        65144 :       return expect_float (static_cast<TyTy::FloatType *> (ltype), rtype);
     417              : 
     418       391491 :     case TyTy::USIZE:
     419       391491 :       return expect_usize (static_cast<TyTy::USizeType *> (ltype), rtype);
     420              : 
     421        69048 :     case TyTy::ISIZE:
     422        69048 :       return expect_isize (static_cast<TyTy::ISizeType *> (ltype), rtype);
     423              : 
     424         4844 :     case TyTy::NEVER:
     425         4844 :       return expect_never (static_cast<TyTy::NeverType *> (ltype), rtype);
     426              : 
     427        14788 :     case TyTy::PLACEHOLDER:
     428        14788 :       return expect_placeholder (static_cast<TyTy::PlaceholderType *> (ltype),
     429        14788 :                                  rtype);
     430              : 
     431            0 :     case TyTy::PROJECTION:
     432            0 :       return expect_projection (static_cast<TyTy::ProjectionType *> (ltype),
     433            0 :                                 rtype);
     434              : 
     435        12916 :     case TyTy::DYNAMIC:
     436        12916 :       return expect_dyn (static_cast<TyTy::DynamicObjectType *> (ltype), rtype);
     437              : 
     438          168 :     case TyTy::CLOSURE:
     439          168 :       return expect_closure (static_cast<TyTy::ClosureType *> (ltype), rtype);
     440              : 
     441           56 :     case TyTy::OPAQUE:
     442           56 :       return expect_opaque (static_cast<TyTy::OpaqueType *> (ltype), rtype);
     443              : 
     444         1786 :     case TyTy::CONST:
     445         1786 :       return expect_const (ltype->as_const_type (), rtype);
     446              : 
     447            4 :     case TyTy::ERROR:
     448            4 :       return unify_error_type_node ();
     449              :     }
     450              : 
     451            0 :   return unify_error_type_node ();
     452              : }
     453              : 
     454              : TyTy::BaseType *
     455        46940 : UnifyRules::expect_inference_variable (TyTy::InferType *ltype,
     456              :                                        TyTy::BaseType *rtype)
     457              : {
     458        46940 :   switch (rtype->get_kind ())
     459              :     {
     460         6425 :     case TyTy::INFER:
     461         6425 :       {
     462         6425 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
     463         6425 :         switch (ltype->get_infer_kind ())
     464              :           {
     465              :           case TyTy::InferType::InferTypeKind::GENERAL:
     466              :             return rtype;
     467              : 
     468         4542 :           case TyTy::InferType::InferTypeKind::INTEGRAL:
     469         4542 :             {
     470         4542 :               bool is_valid = r->get_infer_kind ()
     471              :                                 == TyTy::InferType::InferTypeKind::INTEGRAL
     472         4542 :                               || r->get_infer_kind ()
     473         4964 :                                    == TyTy::InferType::InferTypeKind::GENERAL;
     474         4540 :               if (is_valid)
     475         4540 :                 return rtype;
     476              :             }
     477              :             break;
     478              : 
     479           31 :           case TyTy::InferType::InferTypeKind::FLOAT:
     480           31 :             {
     481           31 :               bool is_valid
     482           31 :                 = r->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT
     483           31 :                   || r->get_infer_kind ()
     484          455 :                        == TyTy::InferType::InferTypeKind::GENERAL;
     485           31 :               if (is_valid)
     486           31 :                 return rtype;
     487              :             }
     488              :             break;
     489              :           }
     490              :       }
     491              :       break;
     492              : 
     493        23435 :     case TyTy::INT:
     494        23435 :     case TyTy::UINT:
     495        23435 :     case TyTy::USIZE:
     496        23435 :     case TyTy::ISIZE:
     497        23435 :       {
     498        23435 :         bool is_valid = (ltype->get_infer_kind ()
     499              :                          == TyTy::InferType::InferTypeKind::GENERAL)
     500        23435 :                         || (ltype->get_infer_kind ()
     501        23859 :                             == TyTy::InferType::InferTypeKind::INTEGRAL);
     502        23435 :         if (is_valid)
     503              :           {
     504        23435 :             if (commit_flag)
     505         2492 :               ltype->apply_primitive_type_hint (*rtype);
     506        23435 :             return rtype;
     507              :           }
     508              :       }
     509              :       break;
     510              : 
     511         4268 :     case TyTy::FLOAT:
     512         4268 :       {
     513         4268 :         bool is_valid = (ltype->get_infer_kind ()
     514              :                          == TyTy::InferType::InferTypeKind::GENERAL)
     515         4268 :                         || (ltype->get_infer_kind ()
     516         4564 :                             == TyTy::InferType::InferTypeKind::FLOAT);
     517         4140 :         if (is_valid)
     518              :           {
     519         4140 :             if (commit_flag)
     520           81 :               ltype->apply_primitive_type_hint (*rtype);
     521         4140 :             return rtype;
     522              :           }
     523              :       }
     524              :       break;
     525              : 
     526        12812 :     case TyTy::ADT:
     527        12812 :     case TyTy::STR:
     528        12812 :     case TyTy::REF:
     529        12812 :     case TyTy::POINTER:
     530        12812 :     case TyTy::PARAM:
     531        12812 :     case TyTy::ARRAY:
     532        12812 :     case TyTy::SLICE:
     533        12812 :     case TyTy::FNDEF:
     534        12812 :     case TyTy::FNPTR:
     535        12812 :     case TyTy::TUPLE:
     536        12812 :     case TyTy::BOOL:
     537        12812 :     case TyTy::CHAR:
     538        12812 :     case TyTy::NEVER:
     539        12812 :     case TyTy::PLACEHOLDER:
     540        12812 :     case TyTy::PROJECTION:
     541        12812 :     case TyTy::DYNAMIC:
     542        12812 :     case TyTy::CLOSURE:
     543        12812 :     case TyTy::CONST:
     544        12812 :     case TyTy::OPAQUE:
     545        12812 :       {
     546        12812 :         bool is_valid = (ltype->get_infer_kind ()
     547        12812 :                          == TyTy::InferType::InferTypeKind::GENERAL);
     548        12812 :         if (is_valid)
     549              :           return rtype;
     550              :       }
     551              :       break;
     552              : 
     553            0 :     case TyTy::ERROR:
     554            0 :       return unify_error_type_node ();
     555              :     }
     556              : 
     557          424 :   return unify_error_type_node ();
     558              : }
     559              : 
     560              : TyTy::BaseType *
     561       232494 : UnifyRules::expect_adt (TyTy::ADTType *ltype, TyTy::BaseType *rtype)
     562              : {
     563       232494 :   switch (rtype->get_kind ())
     564              :     {
     565         2982 :     case TyTy::INFER:
     566         2982 :       {
     567         2982 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
     568         2982 :         bool is_valid
     569         2982 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
     570         2982 :         if (is_valid)
     571              :           return ltype;
     572              :       }
     573              :       break;
     574              : 
     575       109116 :     case TyTy::ADT:
     576       109116 :       {
     577       109116 :         TyTy::ADTType &type = *static_cast<TyTy::ADTType *> (rtype);
     578       109116 :         if (ltype->get_adt_kind () != type.get_adt_kind ())
     579              :           {
     580        22350 :             return unify_error_type_node ();
     581              :           }
     582              : 
     583       260298 :         if (ltype->get_identifier ().compare (type.get_identifier ()) != 0)
     584              :           {
     585        16701 :             return unify_error_type_node ();
     586              :           }
     587              : 
     588        70065 :         if (ltype->number_of_variants () != type.number_of_variants ())
     589              :           {
     590            0 :             return unify_error_type_node ();
     591              :           }
     592              : 
     593       162346 :         for (size_t i = 0; i < type.number_of_variants (); ++i)
     594              :           {
     595        92442 :             TyTy::VariantDef *a = ltype->get_variants ().at (i);
     596        92442 :             TyTy::VariantDef *b = type.get_variants ().at (i);
     597              : 
     598        92442 :             if (a->num_fields () != b->num_fields ())
     599              :               {
     600            0 :                 return unify_error_type_node ();
     601              :               }
     602              : 
     603       196866 :             for (size_t j = 0; j < a->num_fields (); j++)
     604              :               {
     605       104585 :                 TyTy::StructFieldType *base_field = a->get_field_at_index (j);
     606       104585 :                 TyTy::StructFieldType *other_field = b->get_field_at_index (j);
     607              : 
     608       104585 :                 TyTy::BaseType *this_field_ty = base_field->get_field_type ();
     609       104585 :                 TyTy::BaseType *other_field_ty = other_field->get_field_type ();
     610              : 
     611       104585 :                 TyTy::BaseType *unified_ty
     612       104585 :                   = resolve_subtype (TyTy::TyWithLocation (this_field_ty),
     613       104585 :                                      TyTy::TyWithLocation (other_field_ty));
     614       104585 :                 if (unified_ty->get_kind () == TyTy::TypeKind::ERROR)
     615              :                   {
     616          161 :                     return unify_error_type_node ();
     617              :                   }
     618              :               }
     619              :           }
     620              : 
     621              :         // generic args for the unit-struct case
     622        69904 :         if (type.is_unit () && ltype->is_unit ())
     623              :           {
     624         8982 :             rust_assert (type.get_num_substitutions ()
     625              :                          == ltype->get_num_substitutions ());
     626              : 
     627        11107 :             for (size_t i = 0; i < type.get_num_substitutions (); i++)
     628              :               {
     629         2181 :                 auto &a = ltype->get_substs ().at (i);
     630         2181 :                 auto &b = type.get_substs ().at (i);
     631              : 
     632         2181 :                 auto pa = a.get_param_ty ();
     633         2181 :                 auto pb = b.get_param_ty ();
     634              : 
     635         2181 :                 auto res = resolve_subtype (TyTy::TyWithLocation (pa),
     636         2181 :                                             TyTy::TyWithLocation (pb));
     637         2181 :                 if (res->get_kind () == TyTy::TypeKind::ERROR)
     638              :                   {
     639           56 :                     return unify_error_type_node ();
     640              :                   }
     641              :               }
     642              :           }
     643              : 
     644              :         return ltype;
     645              :       }
     646       120396 :       break;
     647              : 
     648       120396 :     case TyTy::STR:
     649       120396 :     case TyTy::REF:
     650       120396 :     case TyTy::POINTER:
     651       120396 :     case TyTy::PARAM:
     652       120396 :     case TyTy::ARRAY:
     653       120396 :     case TyTy::SLICE:
     654       120396 :     case TyTy::FNDEF:
     655       120396 :     case TyTy::FNPTR:
     656       120396 :     case TyTy::TUPLE:
     657       120396 :     case TyTy::BOOL:
     658       120396 :     case TyTy::CHAR:
     659       120396 :     case TyTy::INT:
     660       120396 :     case TyTy::UINT:
     661       120396 :     case TyTy::FLOAT:
     662       120396 :     case TyTy::USIZE:
     663       120396 :     case TyTy::ISIZE:
     664       120396 :     case TyTy::NEVER:
     665       120396 :     case TyTy::PLACEHOLDER:
     666       120396 :     case TyTy::PROJECTION:
     667       120396 :     case TyTy::DYNAMIC:
     668       120396 :     case TyTy::CLOSURE:
     669       120396 :     case TyTy::OPAQUE:
     670       120396 :     case TyTy::CONST:
     671       120396 :     case TyTy::ERROR:
     672       120396 :       return unify_error_type_node ();
     673              :     }
     674            0 :   return unify_error_type_node ();
     675              : }
     676              : 
     677              : TyTy::BaseType *
     678         6982 : UnifyRules::expect_str (TyTy::StrType *ltype, TyTy::BaseType *rtype)
     679              : {
     680         6982 :   switch (rtype->get_kind ())
     681              :     {
     682            0 :     case TyTy::INFER:
     683            0 :       {
     684            0 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
     685            0 :         bool is_valid
     686            0 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
     687            0 :         if (is_valid)
     688              :           return ltype;
     689              :       }
     690              :       break;
     691              : 
     692              :     case TyTy::STR:
     693              :       return rtype;
     694              : 
     695           28 :     case TyTy::ADT:
     696           28 :     case TyTy::REF:
     697           28 :     case TyTy::POINTER:
     698           28 :     case TyTy::PARAM:
     699           28 :     case TyTy::ARRAY:
     700           28 :     case TyTy::SLICE:
     701           28 :     case TyTy::FNDEF:
     702           28 :     case TyTy::FNPTR:
     703           28 :     case TyTy::TUPLE:
     704           28 :     case TyTy::BOOL:
     705           28 :     case TyTy::CHAR:
     706           28 :     case TyTy::INT:
     707           28 :     case TyTy::UINT:
     708           28 :     case TyTy::FLOAT:
     709           28 :     case TyTy::USIZE:
     710           28 :     case TyTy::ISIZE:
     711           28 :     case TyTy::NEVER:
     712           28 :     case TyTy::PLACEHOLDER:
     713           28 :     case TyTy::PROJECTION:
     714           28 :     case TyTy::DYNAMIC:
     715           28 :     case TyTy::CLOSURE:
     716           28 :     case TyTy::OPAQUE:
     717           28 :     case TyTy::CONST:
     718           28 :     case TyTy::ERROR:
     719           28 :       return unify_error_type_node ();
     720              :     }
     721            0 :   return unify_error_type_node ();
     722              : }
     723              : 
     724              : TyTy::BaseType *
     725        64719 : UnifyRules::expect_reference (TyTy::ReferenceType *ltype, TyTy::BaseType *rtype)
     726              : {
     727        64719 :   switch (rtype->get_kind ())
     728              :     {
     729          259 :     case TyTy::INFER:
     730          259 :       {
     731          259 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
     732          259 :         bool is_valid
     733          259 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
     734          259 :         if (is_valid)
     735              :           return ltype;
     736              :       }
     737              :       break;
     738              : 
     739        32219 :     case TyTy::REF:
     740        32219 :       {
     741        32219 :         TyTy::ReferenceType &type = *static_cast<TyTy::ReferenceType *> (rtype);
     742        32219 :         auto base_type = ltype->get_base ();
     743        32219 :         auto other_base_type = type.get_base ();
     744              : 
     745        32219 :         TyTy::BaseType *base_resolved
     746        32219 :           = resolve_subtype (TyTy::TyWithLocation (base_type),
     747        32219 :                              TyTy::TyWithLocation (other_base_type));
     748        32219 :         if (base_resolved->get_kind () == TyTy::TypeKind::ERROR)
     749              :           {
     750        10154 :             return unify_error_type_node ();
     751              :           }
     752              : 
     753              :         // rust is permissive about mutablity here you can always go from
     754              :         // mutable to immutable but not the otherway round
     755        22065 :         bool mutability_ok = ltype->is_mutable () ? type.is_mutable () : true;
     756         1240 :         if (!mutability_ok)
     757              :           {
     758           83 :             return unify_error_type_node ();
     759              :           }
     760              : 
     761              :         return ltype;
     762              :       }
     763        32241 :       break;
     764              : 
     765        32241 :     case TyTy::STR:
     766        32241 :     case TyTy::ADT:
     767        32241 :     case TyTy::POINTER:
     768        32241 :     case TyTy::PARAM:
     769        32241 :     case TyTy::ARRAY:
     770        32241 :     case TyTy::SLICE:
     771        32241 :     case TyTy::FNDEF:
     772        32241 :     case TyTy::FNPTR:
     773        32241 :     case TyTy::TUPLE:
     774        32241 :     case TyTy::BOOL:
     775        32241 :     case TyTy::CHAR:
     776        32241 :     case TyTy::INT:
     777        32241 :     case TyTy::UINT:
     778        32241 :     case TyTy::FLOAT:
     779        32241 :     case TyTy::USIZE:
     780        32241 :     case TyTy::ISIZE:
     781        32241 :     case TyTy::NEVER:
     782        32241 :     case TyTy::PLACEHOLDER:
     783        32241 :     case TyTy::PROJECTION:
     784        32241 :     case TyTy::DYNAMIC:
     785        32241 :     case TyTy::CLOSURE:
     786        32241 :     case TyTy::OPAQUE:
     787        32241 :     case TyTy::CONST:
     788        32241 :     case TyTy::ERROR:
     789        32241 :       return unify_error_type_node ();
     790              :     }
     791            7 :   return unify_error_type_node ();
     792              : }
     793              : 
     794              : TyTy::BaseType *
     795        20403 : UnifyRules::expect_pointer (TyTy::PointerType *ltype, TyTy::BaseType *rtype)
     796              : {
     797        20403 :   switch (rtype->get_kind ())
     798              :     {
     799            0 :     case TyTy::INFER:
     800            0 :       {
     801            0 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
     802            0 :         bool is_valid
     803            0 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
     804            0 :         if (is_valid)
     805              :           return ltype;
     806              :       }
     807              :       break;
     808              : 
     809        15249 :     case TyTy::POINTER:
     810        15249 :       {
     811        15249 :         TyTy::PointerType &type = *static_cast<TyTy::PointerType *> (rtype);
     812        15249 :         auto base_type = ltype->get_base ();
     813        15249 :         auto other_base_type = type.get_base ();
     814              : 
     815        15249 :         TyTy::BaseType *base_resolved
     816        15249 :           = resolve_subtype (TyTy::TyWithLocation (base_type),
     817        15249 :                              TyTy::TyWithLocation (other_base_type));
     818        15249 :         if (base_resolved->get_kind () == TyTy::TypeKind::ERROR)
     819              :           {
     820          161 :             return unify_error_type_node ();
     821              :           }
     822              : 
     823              :         // rust is permissive about mutablity here you can always go from
     824              :         // mutable to immutable but not the otherway round
     825        15088 :         bool mutability_ok = ltype->is_mutable () ? type.is_mutable () : true;
     826         1785 :         if (!mutability_ok)
     827              :           {
     828           28 :             return unify_error_type_node ();
     829              :           }
     830              : 
     831              :         return ltype;
     832              :       }
     833         5154 :       break;
     834              : 
     835         5154 :     case TyTy::STR:
     836         5154 :     case TyTy::ADT:
     837         5154 :     case TyTy::REF:
     838         5154 :     case TyTy::PARAM:
     839         5154 :     case TyTy::ARRAY:
     840         5154 :     case TyTy::SLICE:
     841         5154 :     case TyTy::FNDEF:
     842         5154 :     case TyTy::FNPTR:
     843         5154 :     case TyTy::TUPLE:
     844         5154 :     case TyTy::BOOL:
     845         5154 :     case TyTy::CHAR:
     846         5154 :     case TyTy::INT:
     847         5154 :     case TyTy::UINT:
     848         5154 :     case TyTy::FLOAT:
     849         5154 :     case TyTy::USIZE:
     850         5154 :     case TyTy::ISIZE:
     851         5154 :     case TyTy::NEVER:
     852         5154 :     case TyTy::PLACEHOLDER:
     853         5154 :     case TyTy::PROJECTION:
     854         5154 :     case TyTy::DYNAMIC:
     855         5154 :     case TyTy::CLOSURE:
     856         5154 :     case TyTy::OPAQUE:
     857         5154 :     case TyTy::CONST:
     858         5154 :     case TyTy::ERROR:
     859         5154 :       return unify_error_type_node ();
     860              :     }
     861            0 :   return unify_error_type_node ();
     862              : }
     863              : 
     864              : TyTy::BaseType *
     865        19824 : UnifyRules::expect_param (TyTy::ParamType *ltype, TyTy::BaseType *rtype)
     866              : {
     867        19824 :   switch (rtype->get_kind ())
     868              :     {
     869          400 :     case TyTy::INFER:
     870          400 :       {
     871          400 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
     872          400 :         bool is_valid
     873          400 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
     874          400 :         if (is_valid)
     875              :           return ltype;
     876              :       }
     877              :       break;
     878              : 
     879        19043 :     case TyTy::PARAM:
     880        19043 :       {
     881        19043 :         TyTy::ParamType &type = *static_cast<TyTy::ParamType *> (rtype);
     882              :         // bool symbol_matches
     883              :         //   = ltype->get_symbol ().compare (type.get_symbol ()) == 0;
     884              :         // // TODO
     885              :         // // I think rustc checks a debruinj index
     886              :         // if (symbol_matches)
     887              :         //   {
     888              :         //     return type.clone ();
     889              :         //   }
     890              : 
     891              :         // matching symbol is not going to work when we mix symbol's and have
     892              :         // nested generics
     893              : 
     894              :         // bounds match? FIXME
     895              : 
     896        19043 :         return type.clone ();
     897              :       }
     898          381 :       break;
     899              : 
     900          381 :     case TyTy::POINTER:
     901          381 :     case TyTy::STR:
     902          381 :     case TyTy::ADT:
     903          381 :     case TyTy::REF:
     904          381 :     case TyTy::ARRAY:
     905          381 :     case TyTy::SLICE:
     906          381 :     case TyTy::FNDEF:
     907          381 :     case TyTy::FNPTR:
     908          381 :     case TyTy::TUPLE:
     909          381 :     case TyTy::BOOL:
     910          381 :     case TyTy::CHAR:
     911          381 :     case TyTy::INT:
     912          381 :     case TyTy::UINT:
     913          381 :     case TyTy::FLOAT:
     914          381 :     case TyTy::USIZE:
     915          381 :     case TyTy::ISIZE:
     916          381 :     case TyTy::NEVER:
     917          381 :     case TyTy::PLACEHOLDER:
     918          381 :     case TyTy::PROJECTION:
     919          381 :     case TyTy::DYNAMIC:
     920          381 :     case TyTy::CLOSURE:
     921          381 :     case TyTy::OPAQUE:
     922          381 :     case TyTy::CONST:
     923          381 :     case TyTy::ERROR:
     924          381 :       return unify_error_type_node ();
     925              :     }
     926            0 :   return unify_error_type_node ();
     927              : }
     928              : 
     929              : TyTy::BaseType *
     930        13438 : UnifyRules::expect_array (TyTy::ArrayType *ltype, TyTy::BaseType *rtype)
     931              : {
     932        13438 :   switch (rtype->get_kind ())
     933              :     {
     934          736 :     case TyTy::INFER:
     935          736 :       {
     936          736 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
     937          736 :         bool is_valid
     938          736 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
     939          736 :         if (is_valid)
     940              :           return ltype;
     941              :       }
     942              :       break;
     943              : 
     944         1599 :     case TyTy::ARRAY:
     945         1599 :       {
     946         1599 :         TyTy::ArrayType &type = *static_cast<TyTy::ArrayType *> (rtype);
     947         1599 :         TyTy::BaseType *element_unify
     948         1599 :           = resolve_subtype (TyTy::TyWithLocation (ltype->get_element_type ()),
     949         1599 :                              TyTy::TyWithLocation (type.get_element_type ()));
     950              : 
     951         1599 :         if (element_unify->get_kind () == TyTy::TypeKind::ERROR)
     952            0 :           return unify_error_type_node ();
     953              : 
     954         1599 :         auto ltype_cap = ltype->get_capacity ();
     955         1599 :         auto rtype_cap = type.get_capacity ();
     956              : 
     957              :         // If either capacity is not a const type, return error
     958         1599 :         if (ltype_cap->get_kind () != TyTy::TypeKind::CONST
     959         1599 :             || rtype_cap->get_kind () != TyTy::TypeKind::CONST)
     960            1 :           return unify_error_type_node ();
     961              : 
     962         1598 :         bool save_emit_error = emit_error;
     963         1598 :         emit_error = false;
     964         1598 :         TyTy::BaseType *capacity_unify
     965         1598 :           = resolve_subtype (TyTy::TyWithLocation (ltype_cap),
     966         1598 :                              TyTy::TyWithLocation (rtype_cap));
     967         1598 :         emit_error = save_emit_error;
     968              : 
     969         1598 :         if (capacity_unify->get_kind () != TyTy::TypeKind::CONST)
     970           12 :           return unify_error_type_node ();
     971              : 
     972         1586 :         auto capacity_type_unify = capacity_unify->as_const_type ();
     973         1586 :         if (capacity_type_unify->const_kind ()
     974              :             == TyTy::BaseConstType::ConstKind::Error)
     975            0 :           return unify_error_type_node ();
     976              : 
     977         1586 :         return new TyTy::ArrayType (
     978         1586 :           type.get_ref (), type.get_ty_ref (), type.get_ident ().locus,
     979         1586 :           TyTy::TyVar (capacity_type_unify->as_base_type ()->get_ref ()),
     980         3172 :           TyTy::TyVar (element_unify->get_ref ()));
     981              :       }
     982        11103 :       break;
     983              : 
     984        11103 :     case TyTy::PARAM:
     985        11103 :     case TyTy::POINTER:
     986        11103 :     case TyTy::STR:
     987        11103 :     case TyTy::ADT:
     988        11103 :     case TyTy::REF:
     989        11103 :     case TyTy::SLICE:
     990        11103 :     case TyTy::FNDEF:
     991        11103 :     case TyTy::FNPTR:
     992        11103 :     case TyTy::TUPLE:
     993        11103 :     case TyTy::BOOL:
     994        11103 :     case TyTy::CHAR:
     995        11103 :     case TyTy::INT:
     996        11103 :     case TyTy::UINT:
     997        11103 :     case TyTy::FLOAT:
     998        11103 :     case TyTy::USIZE:
     999        11103 :     case TyTy::ISIZE:
    1000        11103 :     case TyTy::NEVER:
    1001        11103 :     case TyTy::PLACEHOLDER:
    1002        11103 :     case TyTy::PROJECTION:
    1003        11103 :     case TyTy::DYNAMIC:
    1004        11103 :     case TyTy::CLOSURE:
    1005        11103 :     case TyTy::OPAQUE:
    1006        11103 :     case TyTy::CONST:
    1007        11103 :     case TyTy::ERROR:
    1008        11103 :       return unify_error_type_node ();
    1009              :     }
    1010            0 :   return unify_error_type_node ();
    1011              : }
    1012              : 
    1013              : TyTy::BaseType *
    1014         4314 : UnifyRules::expect_slice (TyTy::SliceType *ltype, TyTy::BaseType *rtype)
    1015              : {
    1016         4314 :   switch (rtype->get_kind ())
    1017              :     {
    1018            0 :     case TyTy::INFER:
    1019            0 :       {
    1020            0 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1021            0 :         bool is_valid
    1022            0 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
    1023            0 :         if (is_valid)
    1024              :           return ltype;
    1025              :       }
    1026              :       break;
    1027              : 
    1028         2769 :     case TyTy::SLICE:
    1029         2769 :       {
    1030         2769 :         TyTy::SliceType &type = *static_cast<TyTy::SliceType *> (rtype);
    1031         2769 :         TyTy::BaseType *element_unify
    1032         2769 :           = resolve_subtype (TyTy::TyWithLocation (ltype->get_element_type ()),
    1033         2769 :                              TyTy::TyWithLocation (type.get_element_type ()));
    1034              : 
    1035         2769 :         if (element_unify->get_kind () != TyTy::TypeKind::ERROR)
    1036              :           return ltype;
    1037              :       }
    1038              :       break;
    1039              : 
    1040         1545 :     case TyTy::PARAM:
    1041         1545 :     case TyTy::POINTER:
    1042         1545 :     case TyTy::STR:
    1043         1545 :     case TyTy::ADT:
    1044         1545 :     case TyTy::REF:
    1045         1545 :     case TyTy::ARRAY:
    1046         1545 :     case TyTy::FNDEF:
    1047         1545 :     case TyTy::FNPTR:
    1048         1545 :     case TyTy::TUPLE:
    1049         1545 :     case TyTy::BOOL:
    1050         1545 :     case TyTy::CHAR:
    1051         1545 :     case TyTy::INT:
    1052         1545 :     case TyTy::UINT:
    1053         1545 :     case TyTy::FLOAT:
    1054         1545 :     case TyTy::USIZE:
    1055         1545 :     case TyTy::ISIZE:
    1056         1545 :     case TyTy::NEVER:
    1057         1545 :     case TyTy::PLACEHOLDER:
    1058         1545 :     case TyTy::PROJECTION:
    1059         1545 :     case TyTy::DYNAMIC:
    1060         1545 :     case TyTy::CLOSURE:
    1061         1545 :     case TyTy::OPAQUE:
    1062         1545 :     case TyTy::CONST:
    1063         1545 :     case TyTy::ERROR:
    1064         1545 :       return unify_error_type_node ();
    1065              :     }
    1066            0 :   return unify_error_type_node ();
    1067              : }
    1068              : 
    1069              : TyTy::BaseType *
    1070         4331 : UnifyRules::expect_fndef (TyTy::FnType *ltype, TyTy::BaseType *rtype)
    1071              : {
    1072         4331 :   switch (rtype->get_kind ())
    1073              :     {
    1074            0 :     case TyTy::INFER:
    1075            0 :       {
    1076            0 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1077            0 :         bool is_valid
    1078            0 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
    1079            0 :         if (is_valid)
    1080              :           return ltype;
    1081              :       }
    1082              :       break;
    1083              : 
    1084         4331 :     case TyTy::FNDEF:
    1085         4331 :       {
    1086         4331 :         TyTy::FnType &type = *static_cast<TyTy::FnType *> (rtype);
    1087         4331 :         if (ltype->num_params () != type.num_params ())
    1088              :           {
    1089            0 :             return unify_error_type_node ();
    1090              :           }
    1091              : 
    1092        10831 :         for (size_t i = 0; i < ltype->num_params (); i++)
    1093              :           {
    1094         6505 :             auto a = ltype->param_at (i).get_type ();
    1095         6505 :             auto b = type.param_at (i).get_type ();
    1096              : 
    1097         6505 :             auto unified_param = resolve_subtype (TyTy::TyWithLocation (a),
    1098         6505 :                                                   TyTy::TyWithLocation (b));
    1099         6505 :             if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
    1100              :               {
    1101            5 :                 return unify_error_type_node ();
    1102              :               }
    1103              :           }
    1104              : 
    1105         4326 :         auto unified_return
    1106         4326 :           = resolve_subtype (TyTy::TyWithLocation (ltype->get_return_type ()),
    1107         4326 :                              TyTy::TyWithLocation (type.get_return_type ()));
    1108         4326 :         if (unified_return->get_kind () == TyTy::TypeKind::ERROR)
    1109              :           {
    1110            1 :             return unify_error_type_node ();
    1111              :           }
    1112              : 
    1113              :         // ABI match? see
    1114              :         // https://gcc-rust.zulipchat.com/#narrow/stream/266897-general/topic/extern.20blocks/near/346416045
    1115         4325 :         if (ltype->get_abi () != type.get_abi ())
    1116              :           {
    1117            0 :             if (emit_error)
    1118              :               {
    1119            0 :                 emit_abi_mismatch (*ltype, type);
    1120              :               }
    1121            0 :             return unify_error_type_node ();
    1122              :           }
    1123              : 
    1124              :         // DEF Id match? see https://github.com/Rust-GCC/gccrs/issues/2053
    1125              : 
    1126              :         return ltype;
    1127              :       }
    1128            0 :       break;
    1129              : 
    1130            0 :     case TyTy::TUPLE:
    1131            0 :     case TyTy::BOOL:
    1132            0 :     case TyTy::CHAR:
    1133            0 :     case TyTy::INT:
    1134            0 :     case TyTy::FLOAT:
    1135            0 :     case TyTy::ISIZE:
    1136            0 :     case TyTy::ADT:
    1137            0 :     case TyTy::STR:
    1138            0 :     case TyTy::REF:
    1139            0 :     case TyTy::POINTER:
    1140            0 :     case TyTy::PARAM:
    1141            0 :     case TyTy::ARRAY:
    1142            0 :     case TyTy::SLICE:
    1143            0 :     case TyTy::FNPTR:
    1144            0 :     case TyTy::UINT:
    1145            0 :     case TyTy::USIZE:
    1146            0 :     case TyTy::NEVER:
    1147            0 :     case TyTy::PLACEHOLDER:
    1148            0 :     case TyTy::PROJECTION:
    1149            0 :     case TyTy::DYNAMIC:
    1150            0 :     case TyTy::CLOSURE:
    1151            0 :     case TyTy::OPAQUE:
    1152            0 :     case TyTy::CONST:
    1153            0 :     case TyTy::ERROR:
    1154            0 :       return unify_error_type_node ();
    1155              :     }
    1156            0 :   return unify_error_type_node ();
    1157              : }
    1158              : 
    1159              : TyTy::BaseType *
    1160          336 : UnifyRules::expect_fnptr (TyTy::FnPtr *ltype, TyTy::BaseType *rtype)
    1161              : {
    1162          336 :   switch (rtype->get_kind ())
    1163              :     {
    1164            0 :     case TyTy::INFER:
    1165            0 :       {
    1166            0 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1167            0 :         bool is_valid
    1168            0 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
    1169            0 :         if (is_valid)
    1170              :           return ltype;
    1171              :       }
    1172              :       break;
    1173              : 
    1174          206 :     case TyTy::FNPTR:
    1175          206 :       {
    1176          206 :         TyTy::FnPtr &type = *static_cast<TyTy::FnPtr *> (rtype);
    1177          206 :         if (ltype->num_params () != type.num_params ())
    1178              :           {
    1179            0 :             return unify_error_type_node ();
    1180              :           }
    1181              : 
    1182          248 :         for (size_t i = 0; i < ltype->num_params (); i++)
    1183              :           {
    1184           42 :             auto a = ltype->get_param_type_at (i);
    1185           42 :             auto b = type.get_param_type_at (i);
    1186              : 
    1187           42 :             auto unified_param = resolve_subtype (TyTy::TyWithLocation (a),
    1188           42 :                                                   TyTy::TyWithLocation (b));
    1189           42 :             if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
    1190              :               {
    1191            0 :                 return unify_error_type_node ();
    1192              :               }
    1193              :           }
    1194              : 
    1195          206 :         auto unified_return
    1196          206 :           = resolve_subtype (TyTy::TyWithLocation (ltype->get_return_type ()),
    1197          206 :                              TyTy::TyWithLocation (type.get_return_type ()));
    1198          206 :         if (unified_return->get_kind () == TyTy::TypeKind::ERROR)
    1199              :           {
    1200            0 :             return unify_error_type_node ();
    1201              :           }
    1202              : 
    1203          206 :         if (ltype->get_abi () != type.get_abi ())
    1204              :           {
    1205           58 :             return unify_error_type_node ();
    1206              :           }
    1207              : 
    1208          148 :         if (ltype->get_unsafety () != type.get_unsafety ())
    1209              :           {
    1210           29 :             return unify_error_type_node ();
    1211              :           }
    1212              : 
    1213              :         return ltype;
    1214              :       }
    1215           36 :       break;
    1216              : 
    1217           36 :     case TyTy::FNDEF:
    1218           36 :       {
    1219           36 :         TyTy::FnType &type = *static_cast<TyTy::FnType *> (rtype);
    1220           36 :         auto this_ret_type = ltype->get_return_type ();
    1221           36 :         auto other_ret_type = type.get_return_type ();
    1222              : 
    1223           36 :         auto unified_result
    1224           36 :           = resolve_subtype (TyTy::TyWithLocation (this_ret_type),
    1225           36 :                              TyTy::TyWithLocation (other_ret_type));
    1226           36 :         if (unified_result->get_kind () == TyTy::TypeKind::ERROR)
    1227              :           {
    1228            0 :             return unify_error_type_node ();
    1229              :           }
    1230              : 
    1231           36 :         if (ltype->num_params () != type.num_params ())
    1232              :           {
    1233            0 :             return unify_error_type_node ();
    1234              :           }
    1235              : 
    1236           78 :         for (size_t i = 0; i < ltype->num_params (); i++)
    1237              :           {
    1238           42 :             auto this_param = ltype->get_param_type_at (i);
    1239           42 :             auto other_param = type.param_at (i).get_type ();
    1240              : 
    1241           42 :             auto unified_param
    1242           42 :               = resolve_subtype (TyTy::TyWithLocation (this_param),
    1243           42 :                                  TyTy::TyWithLocation (other_param));
    1244           42 :             if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
    1245              :               {
    1246            0 :                 return unify_error_type_node ();
    1247              :               }
    1248              :           }
    1249              : 
    1250              :         // FIXME
    1251              :         //
    1252              :         // there is a bug in:
    1253              :         // testsuite/rust/compile/try-catch-unwind-{new,old}.rs I think the test
    1254              :         //
    1255              :         // case is wrong because it should be taking an FnOnce which probably
    1256              :         // didnt exist at the time in gccrs
    1257              :         //
    1258              :         // if (ltype->get_abi () != type.get_abi ())
    1259              :         //   {
    1260              :         //     return unify_error_type_node ();
    1261              :         //   }
    1262              : 
    1263              :         // FIXME fntype needs to track unsafe or not
    1264              :         // if (ltype->get_unsafety () != type.get_unsafety ())
    1265              :         //   {
    1266              :         //     return unify_error_type_node ();
    1267              :         //   }
    1268              : 
    1269              :         return ltype;
    1270              :       }
    1271            0 :       break;
    1272              : 
    1273            0 :     case TyTy::CLOSURE:
    1274            0 :       {
    1275            0 :         TyTy::ClosureType &type = *static_cast<TyTy::ClosureType *> (rtype);
    1276            0 :         auto this_ret_type = ltype->get_return_type ();
    1277            0 :         auto other_ret_type = type.get_return_type ();
    1278              : 
    1279            0 :         auto unified_result
    1280            0 :           = resolve_subtype (TyTy::TyWithLocation (this_ret_type),
    1281            0 :                              TyTy::TyWithLocation (other_ret_type));
    1282            0 :         if (unified_result->get_kind () == TyTy::TypeKind::ERROR)
    1283              :           {
    1284            0 :             return unify_error_type_node ();
    1285              :           }
    1286              : 
    1287            0 :         if (ltype->num_params () != type.get_num_params ())
    1288              :           {
    1289            0 :             return unify_error_type_node ();
    1290              :           }
    1291              : 
    1292            0 :         for (size_t i = 0; i < ltype->num_params (); i++)
    1293              :           {
    1294            0 :             auto this_param = ltype->get_param_type_at (i);
    1295            0 :             auto other_param = type.get_param_type_at (i);
    1296              : 
    1297            0 :             auto unified_param
    1298            0 :               = resolve_subtype (TyTy::TyWithLocation (this_param),
    1299            0 :                                  TyTy::TyWithLocation (other_param));
    1300            0 :             if (unified_param->get_kind () == TyTy::TypeKind::ERROR)
    1301              :               {
    1302            0 :                 return unify_error_type_node ();
    1303              :               }
    1304              :           }
    1305              : 
    1306              :         return ltype;
    1307              :       }
    1308           94 :       break;
    1309              : 
    1310           94 :     case TyTy::TUPLE:
    1311           94 :     case TyTy::BOOL:
    1312           94 :     case TyTy::CHAR:
    1313           94 :     case TyTy::INT:
    1314           94 :     case TyTy::FLOAT:
    1315           94 :     case TyTy::ISIZE:
    1316           94 :     case TyTy::ADT:
    1317           94 :     case TyTy::STR:
    1318           94 :     case TyTy::REF:
    1319           94 :     case TyTy::POINTER:
    1320           94 :     case TyTy::PARAM:
    1321           94 :     case TyTy::ARRAY:
    1322           94 :     case TyTy::SLICE:
    1323           94 :     case TyTy::UINT:
    1324           94 :     case TyTy::USIZE:
    1325           94 :     case TyTy::NEVER:
    1326           94 :     case TyTy::PLACEHOLDER:
    1327           94 :     case TyTy::PROJECTION:
    1328           94 :     case TyTy::DYNAMIC:
    1329           94 :     case TyTy::OPAQUE:
    1330           94 :     case TyTy::CONST:
    1331           94 :     case TyTy::ERROR:
    1332           94 :       return unify_error_type_node ();
    1333              :     }
    1334            0 :   return unify_error_type_node ();
    1335              : }
    1336              : 
    1337              : TyTy::BaseType *
    1338        12072 : UnifyRules::expect_tuple (TyTy::TupleType *ltype, TyTy::BaseType *rtype)
    1339              : {
    1340        12072 :   switch (rtype->get_kind ())
    1341              :     {
    1342           59 :     case TyTy::INFER:
    1343           59 :       {
    1344           59 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1345           59 :         bool is_valid
    1346           59 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
    1347           59 :         if (is_valid)
    1348              :           return ltype;
    1349              :       }
    1350              :       break;
    1351              : 
    1352        11723 :     case TyTy::TUPLE:
    1353        11723 :       {
    1354        11723 :         TyTy::TupleType &type = *static_cast<TyTy::TupleType *> (rtype);
    1355        11723 :         if (ltype->num_fields () != type.num_fields ())
    1356              :           {
    1357            2 :             return unify_error_type_node ();
    1358              :           }
    1359              : 
    1360        11721 :         std::vector<TyTy::TyVar> fields;
    1361        13573 :         for (size_t i = 0; i < ltype->num_fields (); i++)
    1362              :           {
    1363         1858 :             TyTy::BaseType *bo = ltype->get_field (i);
    1364         1858 :             TyTy::BaseType *fo = type.get_field (i);
    1365              : 
    1366         1858 :             TyTy::BaseType *unified_ty
    1367         1858 :               = resolve_subtype (TyTy::TyWithLocation (bo),
    1368         1858 :                                  TyTy::TyWithLocation (fo));
    1369         1858 :             if (unified_ty->get_kind () == TyTy::TypeKind::ERROR)
    1370            6 :               return unify_error_type_node ();
    1371              : 
    1372         1852 :             fields.emplace_back (unified_ty->get_ref ());
    1373              :           }
    1374              : 
    1375              :         return ltype;
    1376        11721 :       }
    1377          290 :       break;
    1378              : 
    1379          290 :     case TyTy::BOOL:
    1380          290 :     case TyTy::CHAR:
    1381          290 :     case TyTy::INT:
    1382          290 :     case TyTy::FLOAT:
    1383          290 :     case TyTy::ISIZE:
    1384          290 :     case TyTy::ADT:
    1385          290 :     case TyTy::STR:
    1386          290 :     case TyTy::REF:
    1387          290 :     case TyTy::POINTER:
    1388          290 :     case TyTy::PARAM:
    1389          290 :     case TyTy::ARRAY:
    1390          290 :     case TyTy::SLICE:
    1391          290 :     case TyTy::FNDEF:
    1392          290 :     case TyTy::FNPTR:
    1393          290 :     case TyTy::UINT:
    1394          290 :     case TyTy::USIZE:
    1395          290 :     case TyTy::NEVER:
    1396          290 :     case TyTy::PLACEHOLDER:
    1397          290 :     case TyTy::PROJECTION:
    1398          290 :     case TyTy::DYNAMIC:
    1399          290 :     case TyTy::CLOSURE:
    1400          290 :     case TyTy::OPAQUE:
    1401          290 :     case TyTy::CONST:
    1402          290 :     case TyTy::ERROR:
    1403          290 :       return unify_error_type_node ();
    1404              :     }
    1405            6 :   return unify_error_type_node ();
    1406              : }
    1407              : 
    1408              : TyTy::BaseType *
    1409        19958 : UnifyRules::expect_bool (TyTy::BoolType *ltype, TyTy::BaseType *rtype)
    1410              : {
    1411        19958 :   switch (rtype->get_kind ())
    1412              :     {
    1413          391 :     case TyTy::INFER:
    1414          391 :       {
    1415          391 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1416          391 :         bool is_valid
    1417          391 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
    1418          391 :         if (is_valid)
    1419              :           {
    1420          361 :             if (commit_flag)
    1421            0 :               r->apply_primitive_type_hint (*ltype);
    1422          361 :             return ltype;
    1423              :           }
    1424              :       }
    1425              :       break;
    1426              : 
    1427              :     case TyTy::BOOL:
    1428              :       return rtype;
    1429              : 
    1430         8850 :     case TyTy::CHAR:
    1431         8850 :     case TyTy::INT:
    1432         8850 :     case TyTy::FLOAT:
    1433         8850 :     case TyTy::ISIZE:
    1434         8850 :     case TyTy::ADT:
    1435         8850 :     case TyTy::STR:
    1436         8850 :     case TyTy::REF:
    1437         8850 :     case TyTy::POINTER:
    1438         8850 :     case TyTy::PARAM:
    1439         8850 :     case TyTy::ARRAY:
    1440         8850 :     case TyTy::SLICE:
    1441         8850 :     case TyTy::FNDEF:
    1442         8850 :     case TyTy::FNPTR:
    1443         8850 :     case TyTy::TUPLE:
    1444         8850 :     case TyTy::UINT:
    1445         8850 :     case TyTy::USIZE:
    1446         8850 :     case TyTy::NEVER:
    1447         8850 :     case TyTy::PLACEHOLDER:
    1448         8850 :     case TyTy::PROJECTION:
    1449         8850 :     case TyTy::DYNAMIC:
    1450         8850 :     case TyTy::CLOSURE:
    1451         8850 :     case TyTy::OPAQUE:
    1452         8850 :     case TyTy::CONST:
    1453         8850 :     case TyTy::ERROR:
    1454         8850 :       return unify_error_type_node ();
    1455              :     }
    1456           30 :   return unify_error_type_node ();
    1457              : }
    1458              : 
    1459              : TyTy::BaseType *
    1460         9791 : UnifyRules::expect_char (TyTy::CharType *ltype, TyTy::BaseType *rtype)
    1461              : {
    1462         9791 :   switch (rtype->get_kind ())
    1463              :     {
    1464          316 :     case TyTy::INFER:
    1465          316 :       {
    1466          316 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1467          316 :         bool is_valid
    1468          316 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
    1469          316 :         if (is_valid)
    1470              :           {
    1471          312 :             if (commit_flag)
    1472            0 :               r->apply_primitive_type_hint (*ltype);
    1473          312 :             return ltype;
    1474              :           }
    1475              :       }
    1476              :       break;
    1477              : 
    1478              :     case TyTy::CHAR:
    1479              :       return rtype;
    1480              : 
    1481         8020 :     case TyTy::INT:
    1482         8020 :     case TyTy::FLOAT:
    1483         8020 :     case TyTy::ISIZE:
    1484         8020 :     case TyTy::ADT:
    1485         8020 :     case TyTy::STR:
    1486         8020 :     case TyTy::REF:
    1487         8020 :     case TyTy::POINTER:
    1488         8020 :     case TyTy::PARAM:
    1489         8020 :     case TyTy::ARRAY:
    1490         8020 :     case TyTy::SLICE:
    1491         8020 :     case TyTy::FNDEF:
    1492         8020 :     case TyTy::FNPTR:
    1493         8020 :     case TyTy::TUPLE:
    1494         8020 :     case TyTy::BOOL:
    1495         8020 :     case TyTy::UINT:
    1496         8020 :     case TyTy::USIZE:
    1497         8020 :     case TyTy::NEVER:
    1498         8020 :     case TyTy::PLACEHOLDER:
    1499         8020 :     case TyTy::PROJECTION:
    1500         8020 :     case TyTy::DYNAMIC:
    1501         8020 :     case TyTy::CLOSURE:
    1502         8020 :     case TyTy::OPAQUE:
    1503         8020 :     case TyTy::CONST:
    1504         8020 :     case TyTy::ERROR:
    1505         8020 :       return unify_error_type_node ();
    1506              :     }
    1507            4 :   return unify_error_type_node ();
    1508              : }
    1509              : 
    1510              : TyTy::BaseType *
    1511       305498 : UnifyRules::expect_int (TyTy::IntType *ltype, TyTy::BaseType *rtype)
    1512              : {
    1513       305498 :   switch (rtype->get_kind ())
    1514              :     {
    1515         9766 :     case TyTy::INFER:
    1516         9766 :       {
    1517         9766 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1518         9766 :         bool is_valid
    1519         9766 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
    1520         9766 :             || r->get_infer_kind () == TyTy::InferType::InferTypeKind::INTEGRAL;
    1521         9762 :         if (is_valid)
    1522              :           {
    1523         9762 :             if (commit_flag)
    1524         1369 :               r->apply_primitive_type_hint (*ltype);
    1525         9762 :             return ltype;
    1526              :           }
    1527              :       }
    1528              :       break;
    1529              : 
    1530       131633 :     case TyTy::INT:
    1531       131633 :       {
    1532       131633 :         TyTy::IntType &type = *static_cast<TyTy::IntType *> (rtype);
    1533       131633 :         bool is_valid = ltype->get_int_kind () == type.get_int_kind ();
    1534       131633 :         if (is_valid)
    1535              :           return ltype;
    1536              :       }
    1537              :       break;
    1538              : 
    1539       164099 :     case TyTy::FLOAT:
    1540       164099 :     case TyTy::ISIZE:
    1541       164099 :     case TyTy::ADT:
    1542       164099 :     case TyTy::STR:
    1543       164099 :     case TyTy::REF:
    1544       164099 :     case TyTy::POINTER:
    1545       164099 :     case TyTy::PARAM:
    1546       164099 :     case TyTy::ARRAY:
    1547       164099 :     case TyTy::SLICE:
    1548       164099 :     case TyTy::FNDEF:
    1549       164099 :     case TyTy::FNPTR:
    1550       164099 :     case TyTy::TUPLE:
    1551       164099 :     case TyTy::BOOL:
    1552       164099 :     case TyTy::CHAR:
    1553       164099 :     case TyTy::UINT:
    1554       164099 :     case TyTy::USIZE:
    1555       164099 :     case TyTy::NEVER:
    1556       164099 :     case TyTy::PLACEHOLDER:
    1557       164099 :     case TyTy::PROJECTION:
    1558       164099 :     case TyTy::DYNAMIC:
    1559       164099 :     case TyTy::CLOSURE:
    1560       164099 :     case TyTy::OPAQUE:
    1561       164099 :     case TyTy::CONST:
    1562       164099 :     case TyTy::ERROR:
    1563       164099 :       return unify_error_type_node ();
    1564              :     }
    1565        13262 :   return unify_error_type_node ();
    1566              : }
    1567              : 
    1568              : TyTy::BaseType *
    1569       885026 : UnifyRules::expect_uint (TyTy::UintType *ltype, TyTy::BaseType *rtype)
    1570              : {
    1571       885026 :   switch (rtype->get_kind ())
    1572              :     {
    1573        45895 :     case TyTy::INFER:
    1574        45895 :       {
    1575        45895 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1576        45895 :         bool is_valid
    1577        45895 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
    1578        45895 :             || r->get_infer_kind () == TyTy::InferType::InferTypeKind::INTEGRAL;
    1579        45895 :         if (is_valid)
    1580              :           {
    1581        45895 :             if (commit_flag)
    1582          325 :               r->apply_primitive_type_hint (*ltype);
    1583        45895 :             return ltype;
    1584              :           }
    1585              :       }
    1586              :       break;
    1587              : 
    1588       320712 :     case TyTy::UINT:
    1589       320712 :       {
    1590       320712 :         TyTy::UintType &type = *static_cast<TyTy::UintType *> (rtype);
    1591       320712 :         bool is_valid = ltype->get_uint_kind () == type.get_uint_kind ();
    1592       320712 :         if (is_valid)
    1593              :           return ltype;
    1594              :       }
    1595              :       break;
    1596              : 
    1597       518419 :     case TyTy::FLOAT:
    1598       518419 :     case TyTy::ISIZE:
    1599       518419 :     case TyTy::ADT:
    1600       518419 :     case TyTy::STR:
    1601       518419 :     case TyTy::REF:
    1602       518419 :     case TyTy::POINTER:
    1603       518419 :     case TyTy::PARAM:
    1604       518419 :     case TyTy::ARRAY:
    1605       518419 :     case TyTy::SLICE:
    1606       518419 :     case TyTy::FNDEF:
    1607       518419 :     case TyTy::FNPTR:
    1608       518419 :     case TyTy::TUPLE:
    1609       518419 :     case TyTy::BOOL:
    1610       518419 :     case TyTy::CHAR:
    1611       518419 :     case TyTy::INT:
    1612       518419 :     case TyTy::USIZE:
    1613       518419 :     case TyTy::NEVER:
    1614       518419 :     case TyTy::PLACEHOLDER:
    1615       518419 :     case TyTy::PROJECTION:
    1616       518419 :     case TyTy::DYNAMIC:
    1617       518419 :     case TyTy::CLOSURE:
    1618       518419 :     case TyTy::OPAQUE:
    1619       518419 :     case TyTy::CONST:
    1620       518419 :     case TyTy::ERROR:
    1621       518419 :       return unify_error_type_node ();
    1622              :     }
    1623       213919 :   return unify_error_type_node ();
    1624              : }
    1625              : 
    1626              : TyTy::BaseType *
    1627        65144 : UnifyRules::expect_float (TyTy::FloatType *ltype, TyTy::BaseType *rtype)
    1628              : {
    1629        65144 :   switch (rtype->get_kind ())
    1630              :     {
    1631         1286 :     case TyTy::INFER:
    1632         1286 :       {
    1633         1286 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1634         1286 :         bool is_valid
    1635         1286 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL
    1636         1286 :             || r->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT;
    1637         1254 :         if (is_valid)
    1638              :           {
    1639         1254 :             if (commit_flag)
    1640           40 :               r->apply_primitive_type_hint (*ltype);
    1641         1254 :             return ltype;
    1642              :           }
    1643              :       }
    1644              :       break;
    1645              : 
    1646        13982 :     case TyTy::FLOAT:
    1647        13982 :       {
    1648        13982 :         TyTy::FloatType &type = *static_cast<TyTy::FloatType *> (rtype);
    1649        13982 :         bool is_valid = ltype->get_float_kind () == type.get_float_kind ();
    1650        13982 :         if (is_valid)
    1651              :           return ltype;
    1652              :       }
    1653              :       break;
    1654              : 
    1655        49876 :     case TyTy::ISIZE:
    1656        49876 :     case TyTy::ADT:
    1657        49876 :     case TyTy::STR:
    1658        49876 :     case TyTy::REF:
    1659        49876 :     case TyTy::POINTER:
    1660        49876 :     case TyTy::PARAM:
    1661        49876 :     case TyTy::ARRAY:
    1662        49876 :     case TyTy::SLICE:
    1663        49876 :     case TyTy::FNDEF:
    1664        49876 :     case TyTy::FNPTR:
    1665        49876 :     case TyTy::TUPLE:
    1666        49876 :     case TyTy::BOOL:
    1667        49876 :     case TyTy::CHAR:
    1668        49876 :     case TyTy::INT:
    1669        49876 :     case TyTy::UINT:
    1670        49876 :     case TyTy::USIZE:
    1671        49876 :     case TyTy::NEVER:
    1672        49876 :     case TyTy::PLACEHOLDER:
    1673        49876 :     case TyTy::PROJECTION:
    1674        49876 :     case TyTy::DYNAMIC:
    1675        49876 :     case TyTy::CLOSURE:
    1676        49876 :     case TyTy::OPAQUE:
    1677        49876 :     case TyTy::CONST:
    1678        49876 :     case TyTy::ERROR:
    1679        49876 :       return unify_error_type_node ();
    1680              :     }
    1681         3558 :   return unify_error_type_node ();
    1682              : }
    1683              : 
    1684              : TyTy::BaseType *
    1685        69048 : UnifyRules::expect_isize (TyTy::ISizeType *ltype, TyTy::BaseType *rtype)
    1686              : {
    1687        69048 :   switch (rtype->get_kind ())
    1688              :     {
    1689          817 :     case TyTy::INFER:
    1690          817 :       {
    1691          817 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1692          817 :         bool is_valid
    1693          817 :           = r->get_infer_kind () != TyTy::InferType::InferTypeKind::FLOAT;
    1694          817 :         if (is_valid)
    1695              :           {
    1696          817 :             if (commit_flag)
    1697          332 :               r->apply_primitive_type_hint (*ltype);
    1698          817 :             return ltype;
    1699              :           }
    1700              :       }
    1701              :       break;
    1702              : 
    1703              :     case TyTy::ISIZE:
    1704              :       return rtype;
    1705              : 
    1706        57114 :     case TyTy::ADT:
    1707        57114 :     case TyTy::STR:
    1708        57114 :     case TyTy::REF:
    1709        57114 :     case TyTy::POINTER:
    1710        57114 :     case TyTy::PARAM:
    1711        57114 :     case TyTy::ARRAY:
    1712        57114 :     case TyTy::SLICE:
    1713        57114 :     case TyTy::FNDEF:
    1714        57114 :     case TyTy::FNPTR:
    1715        57114 :     case TyTy::TUPLE:
    1716        57114 :     case TyTy::BOOL:
    1717        57114 :     case TyTy::CHAR:
    1718        57114 :     case TyTy::INT:
    1719        57114 :     case TyTy::UINT:
    1720        57114 :     case TyTy::FLOAT:
    1721        57114 :     case TyTy::USIZE:
    1722        57114 :     case TyTy::NEVER:
    1723        57114 :     case TyTy::PLACEHOLDER:
    1724        57114 :     case TyTy::PROJECTION:
    1725        57114 :     case TyTy::DYNAMIC:
    1726        57114 :     case TyTy::CLOSURE:
    1727        57114 :     case TyTy::OPAQUE:
    1728        57114 :     case TyTy::CONST:
    1729        57114 :     case TyTy::ERROR:
    1730        57114 :       return unify_error_type_node ();
    1731              :     }
    1732            0 :   return unify_error_type_node ();
    1733              : }
    1734              : 
    1735              : TyTy::BaseType *
    1736       391491 : UnifyRules::expect_usize (TyTy::USizeType *ltype, TyTy::BaseType *rtype)
    1737              : {
    1738       391491 :   switch (rtype->get_kind ())
    1739              :     {
    1740        20921 :     case TyTy::INFER:
    1741        20921 :       {
    1742        20921 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1743        20921 :         bool is_valid
    1744        20921 :           = r->get_infer_kind () != TyTy::InferType::InferTypeKind::FLOAT;
    1745        20921 :         if (is_valid)
    1746              :           {
    1747        20921 :             if (commit_flag)
    1748          837 :               r->apply_primitive_type_hint (*ltype);
    1749        20921 :             return ltype;
    1750              :           }
    1751              :       }
    1752              :       break;
    1753              : 
    1754              :     case TyTy::USIZE:
    1755              :       return rtype;
    1756              : 
    1757       311449 :     case TyTy::ADT:
    1758       311449 :     case TyTy::STR:
    1759       311449 :     case TyTy::REF:
    1760       311449 :     case TyTy::POINTER:
    1761       311449 :     case TyTy::PARAM:
    1762       311449 :     case TyTy::ARRAY:
    1763       311449 :     case TyTy::SLICE:
    1764       311449 :     case TyTy::FNDEF:
    1765       311449 :     case TyTy::FNPTR:
    1766       311449 :     case TyTy::TUPLE:
    1767       311449 :     case TyTy::BOOL:
    1768       311449 :     case TyTy::CHAR:
    1769       311449 :     case TyTy::INT:
    1770       311449 :     case TyTy::UINT:
    1771       311449 :     case TyTy::FLOAT:
    1772       311449 :     case TyTy::ISIZE:
    1773       311449 :     case TyTy::NEVER:
    1774       311449 :     case TyTy::PLACEHOLDER:
    1775       311449 :     case TyTy::PROJECTION:
    1776       311449 :     case TyTy::DYNAMIC:
    1777       311449 :     case TyTy::CLOSURE:
    1778       311449 :     case TyTy::OPAQUE:
    1779       311449 :     case TyTy::CONST:
    1780       311449 :     case TyTy::ERROR:
    1781       311449 :       return unify_error_type_node ();
    1782              :     }
    1783            0 :   return unify_error_type_node ();
    1784              : }
    1785              : 
    1786              : TyTy::BaseType *
    1787         4844 : UnifyRules::expect_never (TyTy::NeverType *ltype, TyTy::BaseType *rtype)
    1788              : {
    1789         4844 :   switch (rtype->get_kind ())
    1790              :     {
    1791          342 :     case TyTy::INFER:
    1792          342 :       {
    1793          342 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1794          342 :         bool is_valid
    1795          342 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
    1796          342 :         if (is_valid)
    1797              :           return ltype;
    1798              :       }
    1799            0 :       break;
    1800              : 
    1801              :     default:
    1802              :       return rtype;
    1803              :     }
    1804            0 :   return unify_error_type_node ();
    1805              : }
    1806              : 
    1807              : TyTy::BaseType *
    1808        14788 : UnifyRules::expect_placeholder (TyTy::PlaceholderType *ltype,
    1809              :                                 TyTy::BaseType *rtype)
    1810              : {
    1811        14788 :   switch (rtype->get_kind ())
    1812              :     {
    1813         1123 :     case TyTy::INFER:
    1814         1123 :       {
    1815         1123 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1816         1123 :         bool is_valid
    1817         1123 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
    1818         1123 :         if (is_valid)
    1819              :           return ltype;
    1820              :       }
    1821              :       break;
    1822              : 
    1823              :     case TyTy::PLACEHOLDER:
    1824              :       return ltype;
    1825              : 
    1826        13212 :     case TyTy::PROJECTION:
    1827        13212 :     case TyTy::DYNAMIC:
    1828        13212 :     case TyTy::CLOSURE:
    1829        13212 :     case TyTy::SLICE:
    1830        13212 :     case TyTy::PARAM:
    1831        13212 :     case TyTy::POINTER:
    1832        13212 :     case TyTy::STR:
    1833        13212 :     case TyTy::ADT:
    1834        13212 :     case TyTy::REF:
    1835        13212 :     case TyTy::ARRAY:
    1836        13212 :     case TyTy::FNDEF:
    1837        13212 :     case TyTy::FNPTR:
    1838        13212 :     case TyTy::TUPLE:
    1839        13212 :     case TyTy::BOOL:
    1840        13212 :     case TyTy::CHAR:
    1841        13212 :     case TyTy::INT:
    1842        13212 :     case TyTy::UINT:
    1843        13212 :     case TyTy::FLOAT:
    1844        13212 :     case TyTy::USIZE:
    1845        13212 :     case TyTy::ISIZE:
    1846        13212 :     case TyTy::NEVER:
    1847        13212 :     case TyTy::OPAQUE:
    1848        13212 :       if (infer_flag)
    1849              :         return rtype;
    1850            8 :       gcc_fallthrough ();
    1851              : 
    1852            8 :     case TyTy::CONST:
    1853            8 :     case TyTy::ERROR:
    1854            8 :       return unify_error_type_node ();
    1855              :     }
    1856            0 :   return unify_error_type_node ();
    1857              : }
    1858              : 
    1859              : TyTy::BaseType *
    1860            0 : UnifyRules::expect_projection (TyTy::ProjectionType *ltype,
    1861              :                                TyTy::BaseType *rtype)
    1862              : {
    1863            0 :   switch (rtype->get_kind ())
    1864              :     {
    1865            0 :     case TyTy::INFER:
    1866            0 :       {
    1867            0 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1868            0 :         bool is_valid
    1869            0 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
    1870            0 :         if (is_valid)
    1871              :           return ltype;
    1872              :       }
    1873              :       break;
    1874              : 
    1875              :       // FIXME
    1876            0 :     case TyTy::PROJECTION:
    1877            0 :       rust_unreachable ();
    1878            0 :       break;
    1879              : 
    1880            0 :     case TyTy::DYNAMIC:
    1881            0 :     case TyTy::CLOSURE:
    1882            0 :     case TyTy::SLICE:
    1883            0 :     case TyTy::PARAM:
    1884            0 :     case TyTy::POINTER:
    1885            0 :     case TyTy::STR:
    1886            0 :     case TyTy::ADT:
    1887            0 :     case TyTy::REF:
    1888            0 :     case TyTy::ARRAY:
    1889            0 :     case TyTy::FNDEF:
    1890            0 :     case TyTy::FNPTR:
    1891            0 :     case TyTy::TUPLE:
    1892            0 :     case TyTy::BOOL:
    1893            0 :     case TyTy::CHAR:
    1894            0 :     case TyTy::INT:
    1895            0 :     case TyTy::UINT:
    1896            0 :     case TyTy::FLOAT:
    1897            0 :     case TyTy::USIZE:
    1898            0 :     case TyTy::ISIZE:
    1899            0 :     case TyTy::NEVER:
    1900            0 :     case TyTy::PLACEHOLDER:
    1901            0 :     case TyTy::OPAQUE:
    1902            0 :     case TyTy::CONST:
    1903            0 :     case TyTy::ERROR:
    1904            0 :       return unify_error_type_node ();
    1905              :     }
    1906            0 :   return unify_error_type_node ();
    1907              : }
    1908              : 
    1909              : TyTy::BaseType *
    1910        12916 : UnifyRules::expect_dyn (TyTy::DynamicObjectType *ltype, TyTy::BaseType *rtype)
    1911              : {
    1912        12916 :   switch (rtype->get_kind ())
    1913              :     {
    1914          201 :     case TyTy::INFER:
    1915          201 :       {
    1916          201 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1917          201 :         bool is_valid
    1918          201 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
    1919          201 :         if (is_valid)
    1920              :           return ltype;
    1921              :       }
    1922              :       break;
    1923              : 
    1924          545 :     case TyTy::DYNAMIC:
    1925          545 :       {
    1926          545 :         TyTy::DynamicObjectType &type
    1927              :           = *static_cast<TyTy::DynamicObjectType *> (rtype);
    1928          545 :         if (ltype->num_specified_bounds () != type.num_specified_bounds ())
    1929              :           {
    1930            0 :             return unify_error_type_node ();
    1931              :           }
    1932              : 
    1933          545 :         if (!ltype->bounds_compatible (type, locus, true))
    1934              :           {
    1935            0 :             return unify_error_type_node ();
    1936              :           }
    1937              : 
    1938              :         return ltype;
    1939              :       }
    1940        12170 :       break;
    1941              : 
    1942        12170 :     case TyTy::CLOSURE:
    1943        12170 :     case TyTy::SLICE:
    1944        12170 :     case TyTy::PARAM:
    1945        12170 :     case TyTy::POINTER:
    1946        12170 :     case TyTy::STR:
    1947        12170 :     case TyTy::ADT:
    1948        12170 :     case TyTy::REF:
    1949        12170 :     case TyTy::ARRAY:
    1950        12170 :     case TyTy::FNDEF:
    1951        12170 :     case TyTy::FNPTR:
    1952        12170 :     case TyTy::TUPLE:
    1953        12170 :     case TyTy::BOOL:
    1954        12170 :     case TyTy::CHAR:
    1955        12170 :     case TyTy::INT:
    1956        12170 :     case TyTy::UINT:
    1957        12170 :     case TyTy::FLOAT:
    1958        12170 :     case TyTy::USIZE:
    1959        12170 :     case TyTy::ISIZE:
    1960        12170 :     case TyTy::NEVER:
    1961        12170 :     case TyTy::PLACEHOLDER:
    1962        12170 :     case TyTy::PROJECTION:
    1963        12170 :     case TyTy::OPAQUE:
    1964        12170 :     case TyTy::CONST:
    1965        12170 :     case TyTy::ERROR:
    1966        12170 :       return unify_error_type_node ();
    1967              :     }
    1968            0 :   return unify_error_type_node ();
    1969              : }
    1970              : 
    1971              : TyTy::BaseType *
    1972          168 : UnifyRules::expect_closure (TyTy::ClosureType *ltype, TyTy::BaseType *rtype)
    1973              : {
    1974          168 :   switch (rtype->get_kind ())
    1975              :     {
    1976            0 :     case TyTy::INFER:
    1977            0 :       {
    1978            0 :         TyTy::InferType *r = static_cast<TyTy::InferType *> (rtype);
    1979            0 :         bool is_valid
    1980            0 :           = r->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL;
    1981            0 :         if (is_valid)
    1982              :           return ltype;
    1983              :       }
    1984              :       break;
    1985              : 
    1986          168 :     case TyTy::CLOSURE:
    1987          168 :       {
    1988          168 :         TyTy::ClosureType &type = *static_cast<TyTy::ClosureType *> (rtype);
    1989          168 :         if (ltype->get_def_id () != type.get_def_id ())
    1990              :           {
    1991            7 :             return unify_error_type_node ();
    1992              :           }
    1993              : 
    1994          161 :         TyTy::BaseType *args_res
    1995          161 :           = resolve_subtype (TyTy::TyWithLocation (&ltype->get_parameters ()),
    1996          161 :                              TyTy::TyWithLocation (&type.get_parameters ()));
    1997          161 :         if (args_res->get_kind () == TyTy::TypeKind::ERROR)
    1998              :           {
    1999            0 :             return unify_error_type_node ();
    2000              :           }
    2001              : 
    2002          161 :         TyTy::BaseType *res
    2003          161 :           = resolve_subtype (TyTy::TyWithLocation (&ltype->get_result_type ()),
    2004          161 :                              TyTy::TyWithLocation (&type.get_result_type ()));
    2005          161 :         if (res == nullptr || res->get_kind () == TyTy::TypeKind::ERROR)
    2006              :           {
    2007            0 :             return unify_error_type_node ();
    2008              :           }
    2009              : 
    2010              :         return ltype;
    2011              :       }
    2012            0 :       break;
    2013              : 
    2014            0 :     case TyTy::SLICE:
    2015            0 :     case TyTy::PARAM:
    2016            0 :     case TyTy::POINTER:
    2017            0 :     case TyTy::STR:
    2018            0 :     case TyTy::ADT:
    2019            0 :     case TyTy::REF:
    2020            0 :     case TyTy::ARRAY:
    2021            0 :     case TyTy::FNDEF:
    2022            0 :     case TyTy::FNPTR:
    2023            0 :     case TyTy::TUPLE:
    2024            0 :     case TyTy::BOOL:
    2025            0 :     case TyTy::CHAR:
    2026            0 :     case TyTy::INT:
    2027            0 :     case TyTy::UINT:
    2028            0 :     case TyTy::FLOAT:
    2029            0 :     case TyTy::USIZE:
    2030            0 :     case TyTy::ISIZE:
    2031            0 :     case TyTy::NEVER:
    2032            0 :     case TyTy::PLACEHOLDER:
    2033            0 :     case TyTy::PROJECTION:
    2034            0 :     case TyTy::DYNAMIC:
    2035            0 :     case TyTy::OPAQUE:
    2036            0 :     case TyTy::CONST:
    2037            0 :     case TyTy::ERROR:
    2038            0 :       return unify_error_type_node ();
    2039              :     }
    2040            0 :   return unify_error_type_node ();
    2041              : }
    2042              : 
    2043              : TyTy::BaseType *
    2044           56 : UnifyRules::expect_opaque (TyTy::OpaqueType *ltype, TyTy::BaseType *rtype)
    2045              : {
    2046           56 :   if (rtype->is<TyTy::OpaqueType> ())
    2047              :     {
    2048           28 :       TyTy::OpaqueType *ro = rtype->as<TyTy::OpaqueType> ();
    2049           28 :       if (!ltype->is_equal (*ro))
    2050            0 :         return unify_error_type_node ();
    2051              : 
    2052           28 :       if (ltype->can_resolve () && ro->can_resolve ())
    2053              :         {
    2054           28 :           auto lr = ltype->resolve ();
    2055           28 :           auto rr = ro->resolve ();
    2056              : 
    2057           28 :           auto res = resolve_subtype (TyTy::TyWithLocation (lr),
    2058           28 :                                       TyTy::TyWithLocation (rr));
    2059           28 :           if (res->get_kind () == TyTy::TypeKind::ERROR)
    2060            0 :             return unify_error_type_node ();
    2061              :         }
    2062            0 :       else if (ltype->can_resolve ())
    2063              :         {
    2064            0 :           auto lr = ltype->resolve ();
    2065            0 :           ro->set_ty_ref (lr->get_ref ());
    2066              :         }
    2067            0 :       else if (ro->can_resolve ())
    2068              :         {
    2069            0 :           auto rr = ro->resolve ();
    2070            0 :           ltype->set_ty_ref (rr->get_ref ());
    2071              :         }
    2072              :     }
    2073           28 :   else if (ltype->can_resolve ())
    2074              :     {
    2075            0 :       auto underly = ltype->resolve ();
    2076            0 :       auto res = resolve_subtype (TyTy::TyWithLocation (underly),
    2077            0 :                                   TyTy::TyWithLocation (rtype));
    2078            0 :       if (res->get_kind () == TyTy::TypeKind::ERROR)
    2079            0 :         return unify_error_type_node ();
    2080              :     }
    2081              :   else
    2082              :     {
    2083           28 :       ltype->set_ty_ref (rtype->get_ref ());
    2084              :     }
    2085              : 
    2086              :   return ltype;
    2087              : }
    2088              : 
    2089              : TyTy::BaseType *
    2090         1786 : UnifyRules::expect_const (TyTy::BaseConstType *ltype, TyTy::BaseType *rtype)
    2091              : {
    2092         1786 :   if (rtype->get_kind () != TyTy::TypeKind::CONST)
    2093            0 :     return unify_error_type_node ();
    2094              : 
    2095         1786 :   auto &lhs = *ltype;
    2096         1786 :   auto &rhs = *rtype->as_const_type ();
    2097              : 
    2098              :   // Handle error types early
    2099         1786 :   if (lhs.const_kind () == TyTy::BaseConstType::ConstKind::Error
    2100         1786 :       || rhs.const_kind () == TyTy::BaseConstType::ConstKind::Error)
    2101              :     {
    2102            0 :       auto lhs_base = ltype->as_base_type ();
    2103            0 :       return new TyTy::ConstErrorType (lhs.get_specified_type (),
    2104              :                                        lhs_base->get_ref (),
    2105              :                                        lhs_base->get_ty_ref (),
    2106            0 :                                        lhs_base->get_combined_refs ());
    2107              :     }
    2108              : 
    2109              :   // Try to resolve Decl types (ConstParamType)
    2110         1786 :   TyTy::BaseConstType *resolved_lhs = &lhs;
    2111         1786 :   TyTy::BaseConstType *resolved_rhs = &rhs;
    2112              : 
    2113         1786 :   if (lhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl)
    2114              :     {
    2115           28 :       auto *param = static_cast<TyTy::ConstParamType *> (&lhs);
    2116           28 :       if (param->can_resolve ())
    2117              :         {
    2118            0 :           auto *resolved = param->resolve ();
    2119            0 :           if (resolved->get_kind () == TyTy::TypeKind::CONST)
    2120            0 :             resolved_lhs = resolved->as_const_type ();
    2121              :         }
    2122              :     }
    2123              : 
    2124         1786 :   if (rhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl)
    2125              :     {
    2126           28 :       auto *param = static_cast<TyTy::ConstParamType *> (&rhs);
    2127           28 :       if (param->can_resolve ())
    2128              :         {
    2129            0 :           auto *resolved = param->resolve ();
    2130            0 :           if (resolved->get_kind () == TyTy::TypeKind::CONST)
    2131            0 :             resolved_rhs = resolved->as_const_type ();
    2132              :         }
    2133              :     }
    2134              : 
    2135         3572 :   auto res = resolve_subtype (
    2136         1786 :     TyTy::TyWithLocation (resolved_lhs->get_specified_type ()),
    2137         1786 :     TyTy::TyWithLocation (resolved_rhs->get_specified_type ()));
    2138         1786 :   if (res->get_kind () == TyTy::TypeKind::ERROR)
    2139            0 :     return unify_error_type_node ();
    2140              : 
    2141         1786 :   if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Value
    2142         1786 :       && resolved_rhs->const_kind () == TyTy::BaseConstType::ConstKind::Value)
    2143              :     {
    2144         1653 :       auto vlhs = static_cast<TyTy::ConstValueType &> (*resolved_lhs);
    2145         1653 :       auto vrhs = static_cast<TyTy::ConstValueType &> (*resolved_rhs);
    2146         1653 :       tree lv = vlhs.get_value ();
    2147         1653 :       tree rv = vrhs.get_value ();
    2148              : 
    2149         1653 :       bool ok = operand_equal_p (lv, rv, 0);
    2150         1653 :       if (!ok)
    2151           68 :         return unify_error_type_node ();
    2152              :       else
    2153              :         {
    2154         1585 :           auto lhs_base = resolved_lhs->as_base_type ();
    2155         1585 :           return new TyTy::ConstValueType (lv, res, lhs_base->get_ref (),
    2156              :                                            lhs_base->get_ty_ref (),
    2157         1585 :                                            lhs_base->get_combined_refs ());
    2158              :         }
    2159         1653 :     }
    2160          133 :   else if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Infer
    2161          133 :            && resolved_rhs->const_kind ()
    2162              :                 == TyTy::BaseConstType::ConstKind::Value)
    2163           39 :     return resolved_rhs->as_base_type ();
    2164           94 :   else if (resolved_rhs->const_kind () == TyTy::BaseConstType::ConstKind::Infer
    2165           94 :            && resolved_lhs->const_kind ()
    2166              :                 == TyTy::BaseConstType::ConstKind::Value)
    2167           66 :     return resolved_lhs->as_base_type ();
    2168           28 :   else if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Infer
    2169           28 :            && resolved_rhs->const_kind ()
    2170              :                 == TyTy::BaseConstType::ConstKind::Infer)
    2171            0 :     return resolved_lhs->as_base_type ();
    2172           28 :   else if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl
    2173           28 :            || resolved_rhs->const_kind ()
    2174              :                 == TyTy::BaseConstType::ConstKind::Decl)
    2175              :     {
    2176              :       // If we still have unresolved Decl after trying to resolve, unify with it
    2177              :       // This allows const inference to work
    2178           28 :       if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl
    2179           28 :           && resolved_rhs->const_kind ()
    2180              :                != TyTy::BaseConstType::ConstKind::Decl)
    2181            0 :         return resolved_rhs->as_base_type ();
    2182           28 :       else if (resolved_rhs->const_kind ()
    2183              :                  == TyTy::BaseConstType::ConstKind::Decl
    2184           28 :                && resolved_lhs->const_kind ()
    2185              :                     != TyTy::BaseConstType::ConstKind::Decl)
    2186            0 :         return resolved_lhs->as_base_type ();
    2187              :       // Both are Decl - return lhs
    2188           28 :       return resolved_lhs->as_base_type ();
    2189              :     }
    2190              : 
    2191            0 :   return unify_error_type_node ();
    2192              : }
    2193              : 
    2194              : } // namespace Resolver
    2195              : } // namespace Rust
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.