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

Generated by: LCOV version 2.5.0-beta

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