LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-unify.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 84.3 % 1442 1215
Test Date: 2026-09-19 16:22:48 Functions: 88.6 % 35 31
Legend: Lines:     hit not hit

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