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