LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-typecheck-context.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 87.0 % 578 503
Test Date: 2026-10-24 16:24:59 Functions: 88.7 % 106 94
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-hir-type-check.h"
      20              : #include "rust-type-util.h"
      21              : #include "rust-hir-type-check-expr.h"
      22              : 
      23              : namespace Rust {
      24              : namespace Resolver {
      25              : 
      26              : TypeCheckContext *
      27      7176855 : TypeCheckContext::get ()
      28              : {
      29      7176855 :   static TypeCheckContext *instance;
      30      7176855 :   if (instance == nullptr)
      31         5046 :     instance = new TypeCheckContext ();
      32              : 
      33      7176855 :   return instance;
      34              : }
      35              : 
      36         5046 : TypeCheckContext::TypeCheckContext () { lifetime_resolver_stack.emplace (); }
      37              : 
      38            0 : TypeCheckContext::~TypeCheckContext () {}
      39              : 
      40              : bool
      41            0 : TypeCheckContext::lookup_builtin (NodeId id, TyTy::BaseType **type)
      42              : {
      43            0 :   auto ref_it = node_id_refs.find (id);
      44            0 :   if (ref_it == node_id_refs.end ())
      45              :     return false;
      46              : 
      47            0 :   auto it = resolved.find (ref_it->second);
      48            0 :   if (it == resolved.end ())
      49              :     return false;
      50              : 
      51            0 :   *type = it->second;
      52            0 :   return true;
      53              : }
      54              : 
      55              : bool
      56        37588 : TypeCheckContext::lookup_builtin (std::string name, TyTy::BaseType **type)
      57              : {
      58       424410 :   for (auto &builtin : builtins)
      59              :     {
      60       424410 :       if (name.compare (builtin->as_string ()) == 0)
      61              :         {
      62        37588 :           *type = builtin.get ();
      63        37588 :           return true;
      64              :         }
      65              :     }
      66              :   return false;
      67              : }
      68              : 
      69              : void
      70        96786 : TypeCheckContext::insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type)
      71              : {
      72        96786 :   node_id_refs[ref] = id;
      73        96786 :   resolved[id] = type;
      74        96786 :   builtins.push_back (std::unique_ptr<TyTy::BaseType> (type));
      75        96786 : }
      76              : 
      77              : const std::vector<std::unique_ptr<TyTy::BaseType>> &
      78         4772 : TypeCheckContext::get_builtins () const
      79              : {
      80         4772 :   return builtins;
      81              : }
      82              : 
      83              : void
      84       434293 : TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings,
      85              :                                TyTy::BaseType *type)
      86              : {
      87       434293 :   rust_assert (type != nullptr);
      88       434293 :   NodeId ref = mappings.get_nodeid ();
      89       434293 :   HirId id = mappings.get_hirid ();
      90       434293 :   node_id_refs[ref] = id;
      91       434293 :   resolved[id] = type;
      92       434293 : }
      93              : 
      94              : void
      95       181539 : TypeCheckContext::insert_implicit_type (HirId id, TyTy::BaseType *type)
      96              : {
      97       181539 :   rust_assert (type != nullptr);
      98       181539 :   resolved[id] = type;
      99       181539 : }
     100              : 
     101              : static std::pair<DefId, std::vector<HirId>>
     102        15261 : make_adt_substitution_key (DefId id,
     103              :                            const TyTy::SubstitutionArgumentMappings &mappings)
     104              : {
     105        15261 :   std::vector<HirId> arguments;
     106        15261 :   arguments.reserve (mappings.size ());
     107        32046 :   for (const auto &mapping : mappings.get_mappings ())
     108        16785 :     arguments.push_back (mapping.get_tyty ()->get_ty_ref ());
     109              : 
     110        15261 :   return {id, std::move (arguments)};
     111        15261 : }
     112              : 
     113              : bool
     114         9214 : TypeCheckContext::lookup_adt_substitution (
     115              :   DefId id, const TyTy::SubstitutionArgumentMappings &mappings,
     116              :   TyTy::ADTType **type) const
     117              : {
     118         9214 :   auto it = adt_substitutions.find (make_adt_substitution_key (id, mappings));
     119         9214 :   if (it == adt_substitutions.end ())
     120              :     return false;
     121              : 
     122         3167 :   *type = it->second;
     123         3167 :   return true;
     124              : }
     125              : 
     126              : void
     127         6047 : TypeCheckContext::insert_adt_substitution (
     128              :   DefId id, const TyTy::SubstitutionArgumentMappings &mappings,
     129              :   TyTy::ADTType *type)
     130              : {
     131         6047 :   rust_assert (type != nullptr);
     132         6047 :   auto inserted
     133         6047 :     = adt_substitutions.emplace (make_adt_substitution_key (id, mappings),
     134              :                                  type);
     135         6047 :   rust_assert (inserted.second);
     136         6047 : }
     137              : 
     138              : bool
     139      6313419 : TypeCheckContext::lookup_type (HirId id, TyTy::BaseType **type) const
     140              : {
     141      6313419 :   auto it = resolved.find (id);
     142      6313419 :   if (it == resolved.end ())
     143              :     return false;
     144              : 
     145      6100152 :   *type = it->second;
     146      6100152 :   return true;
     147              : }
     148              : 
     149              : void
     150         3088 : TypeCheckContext::mark_function_body_pending (DefId id)
     151              : {
     152         3088 :   function_bodies_pending.insert (id);
     153         3088 : }
     154              : 
     155              : void
     156        15849 : TypeCheckContext::clear_function_body_pending (DefId id)
     157              : {
     158        15849 :   function_bodies_pending.erase (id);
     159        15849 : }
     160              : 
     161              : bool
     162         3096 : TypeCheckContext::function_body_pending (DefId id) const
     163              : {
     164         3096 :   return function_bodies_pending.find (id) != function_bodies_pending.end ();
     165              : }
     166              : 
     167              : void
     168         4406 : TypeCheckContext::clear_type (TyTy::BaseType *ty)
     169              : {
     170         4406 :   auto it = resolved.find (ty->get_ref ());
     171         4406 :   if (it == resolved.end ())
     172         4406 :     return;
     173              : 
     174         4406 :   resolved.erase (it);
     175              : }
     176              : 
     177              : void
     178            0 : TypeCheckContext::insert_type_by_node_id (NodeId ref, HirId id)
     179              : {
     180            0 :   rust_assert (node_id_refs.find (ref) == node_id_refs.end ());
     181            0 :   node_id_refs[ref] = id;
     182            0 : }
     183              : 
     184              : bool
     185            0 : TypeCheckContext::lookup_type_by_node_id (NodeId ref, HirId *id)
     186              : {
     187            0 :   auto it = node_id_refs.find (ref);
     188            0 :   if (it == node_id_refs.end ())
     189              :     return false;
     190              : 
     191            0 :   *id = it->second;
     192            0 :   return true;
     193              : }
     194              : 
     195              : bool
     196        18139 : TypeCheckContext::have_function_context () const
     197              : {
     198        18139 :   return !return_type_stack.empty ();
     199              : }
     200              : 
     201              : TyTy::BaseType *
     202          642 : TypeCheckContext::peek_return_type ()
     203              : {
     204          642 :   rust_assert (!return_type_stack.empty ());
     205          642 :   return return_type_stack.back ().second;
     206              : }
     207              : 
     208              : void
     209        15849 : TypeCheckContext::push_return_type (TypeCheckContextItem item,
     210              :                                     TyTy::BaseType *return_type)
     211              : {
     212        15849 :   return_type_stack.emplace_back (std::move (item), return_type);
     213              :   // a query can check another function body while an expression in the
     214              :   // caller has an expected type
     215        15849 :   push_expected_type (nullptr);
     216        15849 : }
     217              : 
     218              : void
     219        15849 : TypeCheckContext::pop_return_type ()
     220              : {
     221        15849 :   rust_assert (!return_type_stack.empty ());
     222        15849 :   pop_expected_type ();
     223        15849 :   return_type_stack.pop_back ();
     224        15849 : }
     225              : 
     226              : TypeCheckContextItem
     227        17470 : TypeCheckContext::peek_context ()
     228              : {
     229        17470 :   rust_assert (!return_type_stack.empty ());
     230        17470 :   return return_type_stack.back ().first;
     231              : }
     232              : 
     233              : void
     234        72321 : TypeCheckContext::push_expected_type (TyTy::BaseType *expected)
     235              : {
     236        72321 :   expected_type_stack.push_back (expected);
     237        72321 : }
     238              : 
     239              : void
     240        72321 : TypeCheckContext::pop_expected_type ()
     241              : {
     242        72321 :   rust_assert (!expected_type_stack.empty ());
     243        72321 :   expected_type_stack.pop_back ();
     244        72321 : }
     245              : 
     246              : TyTy::BaseType *
     247        37309 : TypeCheckContext::peek_expected_type () const
     248              : {
     249        37309 :   if (expected_type_stack.empty ())
     250              :     return nullptr;
     251        37022 :   return expected_type_stack.back ();
     252              : }
     253              : 
     254              : StackedContexts<TypeCheckBlockContextItem> &
     255        33348 : TypeCheckContext::block_context ()
     256              : {
     257        33348 :   return block_stack;
     258              : }
     259              : 
     260              : void
     261         4562 : TypeCheckContext::iterate (std::function<bool (HirId, TyTy::BaseType *)> cb)
     262              : {
     263       541319 :   for (auto it = resolved.begin (); it != resolved.end (); it++)
     264              :     {
     265       536757 :       if (!cb (it->first, it->second))
     266         4562 :         return;
     267              :     }
     268              : }
     269              : 
     270              : bool
     271          148 : TypeCheckContext::have_loop_context () const
     272              : {
     273          148 :   return !loop_type_stack.empty ();
     274              : }
     275              : 
     276              : void
     277          155 : TypeCheckContext::push_new_loop_context (HirId id, location_t locus)
     278              : {
     279          155 :   TyTy::BaseType *infer_var
     280              :     = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
     281          155 :                            TyTy::InferType::TypeHint::Default (), locus);
     282          155 :   loop_type_stack.push_back (infer_var);
     283          155 : }
     284              : 
     285              : void
     286           94 : TypeCheckContext::push_new_while_loop_context (HirId id)
     287              : {
     288           94 :   TyTy::BaseType *infer_var = new TyTy::ErrorType (id);
     289           94 :   loop_type_stack.push_back (infer_var);
     290           94 : }
     291              : 
     292              : TyTy::BaseType *
     293          274 : TypeCheckContext::peek_loop_context ()
     294              : {
     295          274 :   return loop_type_stack.back ();
     296              : }
     297              : 
     298              : TyTy::BaseType *
     299          249 : TypeCheckContext::pop_loop_context ()
     300              : {
     301          249 :   auto back = peek_loop_context ();
     302          249 :   loop_type_stack.pop_back ();
     303          249 :   return back;
     304              : }
     305              : 
     306              : void
     307           21 : TypeCheckContext::swap_head_loop_context (TyTy::BaseType *val)
     308              : {
     309           21 :   loop_type_stack.pop_back ();
     310           21 :   loop_type_stack.push_back (val);
     311           21 : }
     312              : 
     313              : bool
     314         3908 : TypeCheckContext::find_matching_impl_trait_frame (
     315              :   const TraitReference &tref, TyTy::BaseType &self,
     316              :   struct ImplTraitContextFrame *find) const
     317              : {
     318         3908 :   if (!have_impl_trait_context ())
     319              :     return false;
     320              : 
     321         2869 :   for (auto it = impl_trait_frame_stack.rbegin ();
     322         2869 :        it != impl_trait_frame_stack.rend (); ++it)
     323              :     {
     324         2088 :       const auto &i = *it;
     325         2088 :       if (!i.trait->is_equal (tref))
     326          675 :         continue;
     327              : 
     328         1413 :       TyTy::BaseType *resolved_self = &self;
     329         1413 :       bool unresolved_trait_self = false;
     330         1413 :       if (auto param = self.try_as<TyTy::ParamType> ())
     331              :         {
     332           85 :           if (param->can_resolve ())
     333           84 :             resolved_self = param->resolve ();
     334              :           else
     335            1 :             unresolved_trait_self = param->is_implicit_self_trait ();
     336              :         }
     337              : 
     338              :       // Select an existing impl context without inferring a new Self
     339              :       // binding
     340         1497 :       bool compatible_self = unresolved_trait_self;
     341           85 :       if (!compatible_self)
     342              :         {
     343         1412 :           auto res
     344         1412 :             = unify_site_and (UNKNOWN_HIRID, TyTy::TyWithLocation (i.self),
     345         1412 :                               TyTy::TyWithLocation (resolved_self),
     346              :                               UNDEF_LOCATION, false /* emit_errors */,
     347              :                               false /* commit */, false /* infer */,
     348              :                               true /* cleanup */, false /* check_bounds */);
     349         1412 :           compatible_self = res->get_kind () != TyTy::TypeKind::ERROR;
     350              :         }
     351              : 
     352         1412 :       if (compatible_self)
     353              :         {
     354         1280 :           *find = i;
     355              :           return true;
     356              :         }
     357              :     }
     358              : 
     359              :   return false;
     360              : }
     361              : 
     362              : bool
     363         3908 : TypeCheckContext::have_impl_trait_context () const
     364              : {
     365         3908 :   return !impl_trait_frame_stack.empty ();
     366              : }
     367              : 
     368              : void
     369        13554 : TypeCheckContext::push_impl_trait_context (struct ImplTraitContextFrame frame)
     370              : {
     371        13554 :   impl_trait_frame_stack.push_back (frame);
     372        13554 : }
     373              : 
     374              : struct ImplTraitContextFrame
     375        13554 : TypeCheckContext::pop_impl_trait_context ()
     376              : {
     377        13554 :   auto back = peek_impl_trait_context ();
     378        13554 :   impl_trait_frame_stack.pop_back ();
     379        13554 :   return back;
     380              : }
     381              : 
     382              : struct ImplTraitContextFrame
     383        13554 : TypeCheckContext::peek_impl_trait_context ()
     384              : {
     385        13554 :   return impl_trait_frame_stack.back ();
     386              : }
     387              : 
     388              : void
     389         4242 : TypeCheckContext::insert_trait_reference (DefId id, TraitReference &&ref)
     390              : {
     391         4242 :   rust_assert (trait_context.find (id) == trait_context.end ());
     392         4242 :   trait_context.emplace (id, std::move (ref));
     393         4242 : }
     394              : 
     395              : bool
     396       521006 : TypeCheckContext::lookup_trait_reference (DefId id, TraitReference **ref)
     397              : {
     398       521006 :   auto it = trait_context.find (id);
     399       521006 :   if (it == trait_context.end ())
     400              :     return false;
     401              : 
     402       493333 :   *ref = &it->second;
     403       493333 :   return true;
     404              : }
     405              : 
     406              : bool
     407         5357 : TypeCheckContext::insert_associated_trait_impl (
     408              :   HirId id, AssociatedImplTrait &&associated)
     409              : {
     410         5357 :   auto it = associated_impl_traits.find (id);
     411         5357 :   if (it != associated_impl_traits.end ())
     412              :     {
     413              :       return false;
     414              :     }
     415         5356 :   associated_impl_traits.emplace (id, std::move (associated));
     416         5356 :   return true;
     417              : }
     418              : 
     419              : bool
     420        26638 : TypeCheckContext::lookup_associated_trait_impl (
     421              :   HirId id, AssociatedImplTrait **associated)
     422              : {
     423        26638 :   auto it = associated_impl_traits.find (id);
     424        26638 :   if (it == associated_impl_traits.end ())
     425              :     return false;
     426              : 
     427        10601 :   *associated = &it->second;
     428        10601 :   return true;
     429              : }
     430              : 
     431              : void
     432            0 : TypeCheckContext::insert_associated_type_mapping (HirId id, HirId mapping)
     433              : {
     434            0 :   associated_type_mappings[id] = mapping;
     435            0 : }
     436              : 
     437              : void
     438            0 : TypeCheckContext::clear_associated_type_mapping (HirId id)
     439              : {
     440            0 :   auto it = associated_type_mappings.find (id);
     441            0 :   if (it != associated_type_mappings.end ())
     442            0 :     associated_type_mappings.erase (it);
     443            0 : }
     444              : 
     445              : // lookup any associated type mappings, the out parameter of mapping is
     446              : // allowed to be nullptr which allows this interface to do a simple does exist
     447              : // check
     448              : bool
     449            0 : TypeCheckContext::lookup_associated_type_mapping (HirId id, HirId *mapping)
     450              : {
     451            0 :   auto it = associated_type_mappings.find (id);
     452            0 :   if (it == associated_type_mappings.end ())
     453              :     return false;
     454              : 
     455            0 :   if (mapping != nullptr)
     456            0 :     *mapping = it->second;
     457              : 
     458              :   return true;
     459              : }
     460              : 
     461              : void
     462         5357 : TypeCheckContext::insert_associated_impl_mapping (HirId trait_id,
     463              :                                                   TyTy::BaseType *impl_type,
     464              :                                                   HirId impl_id)
     465              : {
     466         5357 :   auto it = associated_traits_to_impls.find (trait_id);
     467         5357 :   if (it == associated_traits_to_impls.end ())
     468              :     {
     469         1974 :       associated_traits_to_impls[trait_id] = {};
     470              :     }
     471              : 
     472         5357 :   associated_traits_to_impls[trait_id].emplace_back (impl_type, impl_id);
     473         5357 : }
     474              : 
     475              : bool
     476            0 : TypeCheckContext::lookup_associated_impl_mapping_for_self (HirId trait_id,
     477              :                                                            TyTy::BaseType *self,
     478              :                                                            HirId *mapping)
     479              : {
     480            0 :   auto it = associated_traits_to_impls.find (trait_id);
     481            0 :   if (it == associated_traits_to_impls.end ())
     482              :     return false;
     483              : 
     484            0 :   for (auto &item : it->second)
     485              :     {
     486            0 :       if (types_compatable (TyTy::TyWithLocation (item.first),
     487            0 :                             TyTy::TyWithLocation (self), UNKNOWN_LOCATION,
     488              :                             false))
     489              :         {
     490            0 :           *mapping = item.second;
     491            0 :           return true;
     492              :         }
     493              :     }
     494              :   return false;
     495              : }
     496              : 
     497              : void
     498        49322 : TypeCheckContext::insert_autoderef_mappings (
     499              :   HirId id, std::vector<Adjustment> &&adjustments)
     500              : {
     501        49322 :   autoderef_mappings.emplace (id, std::move (adjustments));
     502        49322 : }
     503              : 
     504              : bool
     505        51920 : TypeCheckContext::lookup_autoderef_mappings (
     506              :   HirId id, std::vector<Adjustment> **adjustments)
     507              : {
     508        51920 :   auto it = autoderef_mappings.find (id);
     509        51920 :   if (it == autoderef_mappings.end ())
     510              :     return false;
     511              : 
     512        38290 :   *adjustments = &it->second;
     513        38290 :   return true;
     514              : }
     515              : 
     516              : void
     517         5752 : TypeCheckContext::insert_cast_autoderef_mappings (
     518              :   HirId id, std::vector<Adjustment> &&adjustments)
     519              : {
     520         5752 :   cast_autoderef_mappings.emplace (id, std::move (adjustments));
     521         5752 : }
     522              : 
     523              : bool
     524         5391 : TypeCheckContext::lookup_cast_autoderef_mappings (
     525              :   HirId id, std::vector<Adjustment> **adjustments)
     526              : {
     527         5391 :   auto it = cast_autoderef_mappings.find (id);
     528         5391 :   if (it == cast_autoderef_mappings.end ())
     529              :     return false;
     530              : 
     531         5391 :   *adjustments = &it->second;
     532         5391 :   return true;
     533              : }
     534              : 
     535              : void
     536         4600 : TypeCheckContext::insert_variant_definition (HirId id, HirId variant)
     537              : {
     538         4600 :   auto it = variants.find (id);
     539         4600 :   rust_assert (it == variants.end ());
     540              : 
     541         4600 :   variants[id] = variant;
     542         4600 : }
     543              : 
     544              : bool
     545         9021 : TypeCheckContext::lookup_variant_definition (HirId id, HirId *variant)
     546              : {
     547         9021 :   auto it = variants.find (id);
     548         9021 :   if (it == variants.end ())
     549              :     return false;
     550              : 
     551         9015 :   *variant = it->second;
     552         9015 :   return true;
     553              : }
     554              : 
     555              : void
     556         1415 : TypeCheckContext::insert_operator_overload (HirId id, TyTy::FnType *call_site)
     557              : {
     558         1415 :   auto it = operator_overloads.find (id);
     559         1415 :   rust_assert (it == operator_overloads.end ());
     560              : 
     561         1415 :   operator_overloads[id] = call_site;
     562         1415 : }
     563              : 
     564              : bool
     565        25735 : TypeCheckContext::lookup_operator_overload (HirId id, TyTy::FnType **call)
     566              : {
     567        25735 :   auto it = operator_overloads.find (id);
     568        25735 :   if (it == operator_overloads.end ())
     569              :     return false;
     570              : 
     571         2512 :   *call = it->second;
     572         2512 :   return true;
     573              : }
     574              : 
     575              : void
     576           15 : TypeCheckContext::insert_deferred_operator_overload (
     577              :   DeferredOpOverload deferred)
     578              : {
     579           15 :   HirId expr_id = deferred.expr_id;
     580           15 :   deferred_operator_overloads.emplace (std::make_pair (expr_id, deferred));
     581           15 : }
     582              : 
     583              : bool
     584            0 : TypeCheckContext::lookup_deferred_operator_overload (
     585              :   HirId id, DeferredOpOverload *deferred)
     586              : {
     587            0 :   auto it = deferred_operator_overloads.find (id);
     588            0 :   if (it == deferred_operator_overloads.end ())
     589              :     return false;
     590              : 
     591            0 :   *deferred = it->second;
     592            0 :   return true;
     593              : }
     594              : 
     595              : void
     596            0 : TypeCheckContext::iterate_deferred_operator_overloads (
     597              :   std::function<bool (HirId, DeferredOpOverload &)> cb)
     598              : {
     599            0 :   for (auto it = deferred_operator_overloads.begin ();
     600            0 :        it != deferred_operator_overloads.end (); it++)
     601              :     {
     602            0 :       if (!cb (it->first, it->second))
     603            0 :         return;
     604              :     }
     605              : }
     606              : 
     607              : void
     608         6463 : TypeCheckContext::insert_unconstrained_check_marker (HirId id, bool status)
     609              : {
     610         6463 :   unconstrained[id] = status;
     611         6463 : }
     612              : 
     613              : bool
     614        35038 : TypeCheckContext::have_checked_for_unconstrained (HirId id, bool *result)
     615              : {
     616        35038 :   auto it = unconstrained.find (id);
     617        35038 :   bool found = it != unconstrained.end ();
     618        35038 :   if (!found)
     619              :     return false;
     620              : 
     621        28575 :   *result = it->second;
     622        28575 :   return true;
     623              : }
     624              : 
     625              : void
     626         7974 : TypeCheckContext::insert_resolved_predicate (
     627              :   HirId id, const TyTy::TypeBoundPredicate &predicate)
     628              : {
     629              :   // auto it = predicates.find (id);
     630              :   // rust_assert (it == predicates.end ());
     631              : 
     632         7974 :   predicates.emplace (id, predicate);
     633         7974 : }
     634              : 
     635              : bool
     636        34344 : TypeCheckContext::lookup_predicate (HirId id, TyTy::TypeBoundPredicate *result)
     637              : {
     638        34344 :   auto it = predicates.find (id);
     639        34344 :   bool found = it != predicates.end ();
     640        34344 :   if (!found)
     641              :     return false;
     642              : 
     643        26022 :   *result = it->second;
     644        26022 :   return true;
     645              : }
     646              : 
     647              : std::vector<TyTy::TypeBoundPredicate>
     648        10505 : TypeCheckContext::predicates_for_type (const TyTy::BaseType *receiver) const
     649              : {
     650        10505 :   std::vector<TyTy::TypeBoundPredicate> result
     651        10505 :     = receiver->get_specified_bounds ();
     652              : 
     653       166826 :   for (const auto &entry : predicates)
     654              :     {
     655       156321 :       const auto &predicate = entry.second;
     656       156321 :       const auto &args = predicate.get_substitution_arguments ();
     657       156321 :       if (args.get_mappings ().empty ())
     658       156316 :         continue;
     659              : 
     660       156321 :       TyTy::BaseType *bound_self = args.get_mappings ().front ().get_tyty ();
     661       175551 :       if (bound_self == nullptr
     662       156321 :           || bound_self->get_kind () == TyTy::TypeKind::ERROR)
     663        19230 :         continue;
     664              : 
     665       137091 :       if (receiver->get_kind () != TyTy::TypeKind::PROJECTION
     666       137091 :           || bound_self->get_kind () != TyTy::TypeKind::PROJECTION)
     667       137083 :         continue;
     668              : 
     669            8 :       const auto *receiver_projection
     670              :         = static_cast<const TyTy::ProjectionType *> (receiver);
     671            8 :       const auto *bound_projection
     672              :         = static_cast<const TyTy::ProjectionType *> (bound_self);
     673              : 
     674            8 :       DefId receiver_item_defid = receiver_projection->get_item_defid ();
     675            8 :       DefId bound_item_defid = bound_projection->get_item_defid ();
     676            8 :       bool same_item = receiver_item_defid == bound_item_defid;
     677            8 :       if (!same_item)
     678            1 :         continue;
     679              : 
     680            7 :       DefId receiver_trait_defid
     681            7 :         = receiver_projection->get_trait_ref ()->get_mappings ().get_defid ();
     682            7 :       DefId bound_trait_defid
     683            7 :         = bound_projection->get_trait_ref ()->get_mappings ().get_defid ();
     684            7 :       bool same_trait = receiver_trait_defid == bound_trait_defid;
     685            7 :       if (!same_trait)
     686            0 :         continue;
     687              : 
     688              :       // Compatibility can unify unrelated parameters. Match their declaration
     689              :       // identities instead; copies and synthetic bound parameters retain them.
     690            7 :       const TyTy::BaseType *receiver_self = receiver_projection->get_self ();
     691            7 :       const TyTy::BaseType *bound_self_ty = bound_projection->get_self ();
     692            7 :       const auto *receiver_param
     693            7 :         = receiver_self->try_as<const TyTy::ParamType> ();
     694            7 :       const auto *bound_param = bound_self_ty->try_as<const TyTy::ParamType> ();
     695              : 
     696            7 :       bool either_self_is_param
     697            7 :         = receiver_param != nullptr || bound_param != nullptr;
     698            7 :       if (either_self_is_param)
     699              :         {
     700            7 :           bool both_selfs_are_param
     701              :             = receiver_param != nullptr && bound_param != nullptr;
     702            7 :           bool same_declaration
     703              :             = both_selfs_are_param
     704            7 :               && receiver_param->get_decl_id () == bound_param->get_decl_id ();
     705            2 :           if (!same_declaration)
     706            2 :             continue;
     707              :         }
     708              :       else
     709              :         {
     710            0 :           bool selfs_compatible = types_compatable (
     711            0 :             TyTy::TyWithLocation (const_cast<TyTy::BaseType *> (receiver_self)),
     712            0 :             TyTy::TyWithLocation (const_cast<TyTy::BaseType *> (bound_self_ty)),
     713              :             UNKNOWN_LOCATION, false, false);
     714            0 :           if (!selfs_compatible)
     715            0 :             continue;
     716              :         }
     717              : 
     718            5 :       bool projections_compatible = types_compatable (
     719            5 :         TyTy::TyWithLocation (const_cast<TyTy::BaseType *> (receiver)),
     720            5 :         TyTy::TyWithLocation (bound_self), UNKNOWN_LOCATION, false, false);
     721            5 :       if (projections_compatible)
     722            5 :         result.push_back (predicate);
     723              :     }
     724              : 
     725        10505 :   return result;
     726              : }
     727              : 
     728              : void
     729         8127 : TypeCheckContext::insert_query (HirId id)
     730              : {
     731         8127 :   querys_in_progress.insert (id);
     732         8127 : }
     733              : 
     734              : void
     735         8127 : TypeCheckContext::query_completed (HirId id)
     736              : {
     737         8127 :   querys_in_progress.erase (id);
     738         8127 : }
     739              : 
     740              : bool
     741         8572 : TypeCheckContext::query_in_progress (HirId id) const
     742              : {
     743         8572 :   return querys_in_progress.find (id) != querys_in_progress.end ();
     744              : }
     745              : 
     746              : void
     747         4257 : TypeCheckContext::insert_trait_query (DefId id)
     748              : {
     749         4257 :   trait_queries_in_progress.insert (id);
     750         4257 : }
     751              : 
     752              : void
     753         4257 : TypeCheckContext::trait_query_completed (DefId id)
     754              : {
     755         4257 :   trait_queries_in_progress.erase (id);
     756         4257 : }
     757              : 
     758              : bool
     759         4261 : TypeCheckContext::trait_query_in_progress (DefId id) const
     760              : {
     761         4261 :   return trait_queries_in_progress.find (id)
     762         4261 :          != trait_queries_in_progress.end ();
     763              : }
     764              : 
     765              : Lifetime
     766          940 : TypeCheckContext::intern_lifetime (const HIR::Lifetime &lifetime)
     767              : {
     768          940 :   if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
     769              :     {
     770          939 :       auto maybe_interned = lookup_lifetime (lifetime);
     771          939 :       if (maybe_interned)
     772          830 :         return *maybe_interned;
     773              : 
     774          109 :       auto interned = next_lifetime_index.next ();
     775          109 :       lifetime_name_interner[lifetime.get_name ()] = interned;
     776          109 :       return interned;
     777              :     }
     778            1 :   if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
     779              :     {
     780            1 :       return next_lifetime_index.next ();
     781              :     }
     782            0 :   if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
     783              :     {
     784            0 :       return Lifetime::static_lifetime ();
     785              :     }
     786            0 :   rust_unreachable ();
     787              : }
     788              : 
     789              : tl::optional<Lifetime>
     790        10833 : TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const
     791              : {
     792        10833 :   if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
     793              :     {
     794         1257 :       if (lifetime.get_name () == "static")
     795              :         {
     796            1 :           rich_location r (line_table, lifetime.get_locus ());
     797            1 :           r.add_fixit_insert_after (lifetime.get_locus (),
     798              :                                     "static is a reserved lifetime name");
     799            1 :           rust_error_at (r, ErrorCode::E0262,
     800              :                          "invalid lifetime parameter name: %qs",
     801            1 :                          lifetime.get_name ().c_str ());
     802            1 :           return tl::nullopt;
     803            1 :         }
     804         1256 :       const auto name = lifetime.get_name ();
     805         1256 :       auto it = lifetime_name_interner.find (name);
     806         1256 :       if (it == lifetime_name_interner.end ())
     807          113 :         return tl::nullopt;
     808         1143 :       return it->second;
     809         1256 :     }
     810         9576 :   if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
     811              :     {
     812         9476 :       return Lifetime::anonymous_lifetime ();
     813              :     }
     814          100 :   if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
     815              :     {
     816          100 :       return Lifetime::static_lifetime ();
     817              :     }
     818            0 :   rust_unreachable ();
     819              : }
     820              : 
     821              : WARN_UNUSED_RESULT tl::optional<TyTy::Region>
     822         9894 : TypeCheckContext::lookup_and_resolve_lifetime (
     823              :   const HIR::Lifetime &lifetime) const
     824              : {
     825         9894 :   auto maybe_interned = lookup_lifetime (lifetime);
     826         9894 :   if (!maybe_interned)
     827            5 :     return tl::nullopt;
     828              : 
     829         9889 :   return get_lifetime_resolver ().resolve (maybe_interned.value ());
     830              : }
     831              : void
     832           41 : TypeCheckContext::intern_and_insert_lifetime (const HIR::Lifetime &lifetime)
     833              : {
     834           41 :   get_lifetime_resolver ().insert_mapping (intern_lifetime (lifetime));
     835           41 : }
     836              : 
     837              : WARN_UNUSED_RESULT std::vector<TyTy::Region>
     838        11061 : TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
     839              : {
     840        11061 :   std::vector<TyTy::Region> regions;
     841        11103 :   for (const auto &lifetime : args.get_lifetime_args ())
     842              :     {
     843           43 :       auto resolved = lookup_and_resolve_lifetime (lifetime);
     844           43 :       if (!resolved)
     845              :         {
     846            1 :           rust_error_at (lifetime.get_locus (), "unresolved lifetime");
     847            1 :           return {};
     848              :         }
     849           42 :       regions.push_back (*resolved);
     850              :     }
     851        11060 :   return regions;
     852        11061 : }
     853              : 
     854              : bool
     855           15 : TypeCheckContext::compute_ambigious_op_overload (HirId id,
     856              :                                                  DeferredOpOverload &op)
     857              : {
     858           15 :   rust_debug ("attempting resolution of deferred operator overload");
     859              : 
     860           15 :   TyTy::BaseType *lhs = nullptr;
     861           15 :   bool ok = lookup_type (op.op.get_lvalue_mappings ().get_hirid (), &lhs);
     862           15 :   rust_assert (ok);
     863              : 
     864           15 :   TyTy::BaseType *rhs = nullptr;
     865           15 :   if (op.op.has_rvalue_mappings ())
     866              :     {
     867           15 :       bool ok = lookup_type (op.op.get_rvalue_mappings ().get_hirid (), &rhs);
     868           15 :       rust_assert (ok);
     869              :     }
     870              : 
     871           15 :   TyTy::BaseType *current_result = op.result_type.get_tyty ();
     872           15 :   rust_assert (current_result != nullptr);
     873              : 
     874           15 :   rust_debug ("deferred operator expr=%u lhs=%s rhs=%s "
     875              :               "stored-result=%s current-result=%s result-ref=%u ty-ref=%u",
     876              :               id, lhs->debug_str ().c_str (),
     877              :               rhs == nullptr ? "<none>" : rhs->debug_str ().c_str (),
     878              :               current_result->debug_str ().c_str (),
     879              :               current_result->debug_str ().c_str (), op.result_type.get_ref (),
     880              :               current_result->get_ty_ref ());
     881              : 
     882           15 :   TyTy::BaseType *resolved
     883           15 :     = TypeCheckExpr::ResolveOpOverload (op.lang_item_type, op.op, lhs, rhs,
     884           15 :                                         op.specified_segment, current_result);
     885           15 :   if (resolved == nullptr)
     886              :     return false;
     887              : 
     888           15 :   TyTy::BaseType *result
     889           15 :     = unify_site (id, TyTy::TyWithLocation (current_result),
     890           15 :                   TyTy::TyWithLocation (resolved), op.op.get_locus ());
     891           15 :   rust_assert (result != nullptr);
     892           15 :   rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
     893              : 
     894              :   return true;
     895              : }
     896              : 
     897              : void
     898         4562 : TypeCheckContext::compute_inference_variables (bool emit_error)
     899              : {
     900         9124 :   auto resolve_deferred_operator_overloads = [this] () {
     901         9139 :     bool progress;
     902         9139 :     do
     903              :       {
     904         9139 :         progress = false;
     905         9139 :         for (auto it = deferred_operator_overloads.begin ();
     906         9154 :              it != deferred_operator_overloads.end ();)
     907              :           {
     908           15 :             if (compute_ambigious_op_overload (it->first, it->second))
     909              :               {
     910           15 :                 it = deferred_operator_overloads.erase (it);
     911           15 :                 progress = true;
     912              :               }
     913              :             else
     914            0 :               ++it;
     915              :           }
     916              :       }
     917              :     while (progress);
     918        13686 :   };
     919              : 
     920         4562 :   resolve_deferred_operator_overloads ();
     921              : 
     922         4562 :   iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
     923       536757 :     return compute_infer_var (id, ty, emit_error);
     924              :   });
     925              : 
     926         4562 :   resolve_deferred_operator_overloads ();
     927         4562 : }
     928              : 
     929              : bool
     930       536757 : TypeCheckContext::compute_infer_var (HirId id, TyTy::BaseType *ty,
     931              :                                      bool emit_error)
     932              : {
     933       536757 :   auto &mappings = Analysis::Mappings::get ();
     934              : 
     935              :   // nothing to do
     936       536757 :   if (ty->get_kind () != TyTy::TypeKind::INFER)
     937              :     return true;
     938              : 
     939         1616 :   TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
     940         1616 :   TyTy::BaseType *default_type;
     941              : 
     942         1616 :   TyTy::BaseType *current = TyTy::TyVar (ty->get_ref ()).get_tyty ();
     943         1616 :   rust_assert (current != nullptr);
     944              : 
     945         1616 :   rust_debug_loc (mappings.lookup_location (id),
     946              :                   "trying to default infer-var id=%u ref=%u ty-ref=%u "
     947              :                   "stored=%s current=%s",
     948              :                   id, ty->get_ref (), ty->get_ty_ref (),
     949              :                   infer_var->debug_str ().c_str (),
     950              :                   current->debug_str ().c_str ());
     951         1616 :   bool ok = infer_var->default_type (&default_type);
     952         1616 :   if (!ok)
     953              :     {
     954            8 :       if (emit_error)
     955            8 :         rust_error_at (mappings.lookup_location (id), ErrorCode::E0282,
     956              :                        "type annotations needed");
     957              :       return true;
     958              :     }
     959              : 
     960         1608 :   rust_debug_loc (mappings.lookup_location (id), "default type selected: %s",
     961              :                   default_type->debug_str ().c_str ());
     962              : 
     963         1608 :   auto result
     964         1608 :     = unify_site (id, TyTy::TyWithLocation (ty),
     965         1608 :                   TyTy::TyWithLocation (default_type), UNDEF_LOCATION);
     966         1608 :   rust_assert (result);
     967         1608 :   rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
     968         1608 :   result->set_ref (id);
     969         1608 :   insert_implicit_type (id, result);
     970              : 
     971         1608 :   return true;
     972              : }
     973              : 
     974              : TyTy::VarianceAnalysis::CrateCtx &
     975         8893 : TypeCheckContext::get_variance_analysis_ctx ()
     976              : {
     977         8893 :   return variance_analysis_ctx;
     978              : }
     979              : 
     980              : // TypeCheckContextItem
     981              : 
     982        10278 : TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
     983              : 
     984         7915 : TypeCheckContextItem::Item::Item (HIR::ImplBlock *impl_block,
     985              :                                   HIR::Function *item)
     986         7915 :   : impl_item ({impl_block, item})
     987         7915 : {}
     988              : 
     989          869 : TypeCheckContextItem::Item::Item (HIR::TraitItemFunc *trait_item)
     990          869 :   : trait_item (trait_item)
     991          869 : {}
     992              : 
     993         7065 : TypeCheckContextItem::TypeCheckContextItem (HIR::Function *item)
     994         7065 :   : type (ItemType::ITEM), item (item)
     995         7065 : {}
     996              : 
     997         7915 : TypeCheckContextItem::TypeCheckContextItem (HIR::ImplBlock &impl_block,
     998              :                                             HIR::Function *item)
     999         7915 :   : type (ItemType::IMPL_ITEM), item (&impl_block, item)
    1000         7915 : {}
    1001              : 
    1002          869 : TypeCheckContextItem::TypeCheckContextItem (HIR::TraitItemFunc *trait_item)
    1003          869 :   : type (ItemType::TRAIT_ITEM), item (trait_item)
    1004          869 : {}
    1005              : 
    1006        33402 : TypeCheckContextItem::TypeCheckContextItem (const TypeCheckContextItem &other)
    1007        33402 :   : type (other.type), item (other.item)
    1008              : {
    1009        33402 :   switch (other.type)
    1010              :     {
    1011        15616 :     case ITEM:
    1012        15616 :       item.item = other.item.item;
    1013        15616 :       break;
    1014              : 
    1015        16353 :     case IMPL_ITEM:
    1016        16353 :       item.impl_item = other.item.impl_item;
    1017        16353 :       break;
    1018              : 
    1019         1433 :     case TRAIT_ITEM:
    1020         1433 :       item.trait_item = other.item.trait_item;
    1021         1433 :       break;
    1022              : 
    1023            0 :     case ERROR:
    1024            0 :       item.item = nullptr;
    1025            0 :       break;
    1026              :     }
    1027        33402 : }
    1028              : 
    1029         3213 : TypeCheckContextItem::TypeCheckContextItem ()
    1030         3213 :   : type (ItemType::ERROR), item (static_cast<HIR::Function *> (nullptr))
    1031         3213 : {}
    1032              : 
    1033              : TypeCheckContextItem &
    1034         3198 : TypeCheckContextItem::operator= (const TypeCheckContextItem &other)
    1035              : {
    1036         3198 :   type = other.type;
    1037         3198 :   switch (other.type)
    1038              :     {
    1039          721 :     case ITEM:
    1040          721 :       item.item = other.item.item;
    1041          721 :       break;
    1042              : 
    1043         2363 :     case IMPL_ITEM:
    1044         2363 :       item.impl_item = other.item.impl_item;
    1045         2363 :       break;
    1046              : 
    1047          114 :     case TRAIT_ITEM:
    1048          114 :       item.trait_item = other.item.trait_item;
    1049          114 :       break;
    1050              : 
    1051            0 :     case ERROR:
    1052            0 :       item.item = nullptr;
    1053            0 :       break;
    1054              :     }
    1055              : 
    1056         3198 :   return *this;
    1057              : }
    1058              : 
    1059              : TypeCheckContextItem
    1060         3213 : TypeCheckContextItem::get_error ()
    1061              : {
    1062         3213 :   return TypeCheckContextItem ();
    1063              : }
    1064              : 
    1065              : bool
    1066            0 : TypeCheckContextItem::is_error () const
    1067              : {
    1068            0 :   return type == ERROR;
    1069              : }
    1070              : 
    1071              : HIR::Function *
    1072           63 : TypeCheckContextItem::get_item ()
    1073              : {
    1074           63 :   rust_assert (get_type () == ItemType::ITEM);
    1075           63 :   return item.item;
    1076              : }
    1077              : 
    1078              : std::pair<HIR::ImplBlock *, HIR::Function *> &
    1079          781 : TypeCheckContextItem::get_impl_item ()
    1080              : {
    1081          781 :   rust_assert (get_type () == ItemType::IMPL_ITEM);
    1082          781 :   return item.impl_item;
    1083              : }
    1084              : 
    1085              : HIR::TraitItemFunc *
    1086            1 : TypeCheckContextItem::get_trait_item ()
    1087              : {
    1088            1 :   rust_assert (get_type () == ItemType::TRAIT_ITEM);
    1089            1 :   return item.trait_item;
    1090              : }
    1091              : 
    1092              : TypeCheckContextItem::ItemType
    1093        20134 : TypeCheckContextItem::get_type () const
    1094              : {
    1095        20134 :   return type;
    1096              : }
    1097              : 
    1098              : TyTy::FnType *
    1099           64 : TypeCheckContextItem::get_context_type ()
    1100              : {
    1101           64 :   auto &context = *TypeCheckContext::get ();
    1102              : 
    1103           64 :   HirId reference = UNKNOWN_HIRID;
    1104           64 :   switch (get_type ())
    1105              :     {
    1106           63 :     case ITEM:
    1107           63 :       reference = get_item ()->get_mappings ().get_hirid ();
    1108           63 :       break;
    1109              : 
    1110            0 :     case IMPL_ITEM:
    1111            0 :       reference = get_impl_item ().second->get_mappings ().get_hirid ();
    1112            0 :       break;
    1113              : 
    1114            1 :     case TRAIT_ITEM:
    1115            1 :       reference = get_trait_item ()->get_mappings ().get_hirid ();
    1116            1 :       break;
    1117              : 
    1118            0 :     case ERROR:
    1119            0 :       rust_unreachable ();
    1120              :       return nullptr;
    1121              :     }
    1122              : 
    1123           64 :   rust_assert (reference != UNKNOWN_HIRID);
    1124              : 
    1125           64 :   TyTy::BaseType *lookup = nullptr;
    1126           64 :   bool ok = context.lookup_type (reference, &lookup);
    1127           64 :   rust_assert (ok);
    1128           64 :   rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
    1129           64 :   return static_cast<TyTy::FnType *> (lookup);
    1130              : }
    1131              : 
    1132              : DefId
    1133         3439 : TypeCheckContextItem::get_defid () const
    1134              : {
    1135         3439 :   switch (get_type ())
    1136              :     {
    1137          959 :     case ITEM:
    1138          959 :       return item.item->get_mappings ().get_defid ();
    1139              : 
    1140         2270 :     case IMPL_ITEM:
    1141         2270 :       return item.impl_item.second->get_mappings ().get_defid ();
    1142              : 
    1143          114 :     case TRAIT_ITEM:
    1144          114 :       return item.trait_item->get_mappings ().get_defid ();
    1145              : 
    1146           96 :     case ERROR:
    1147           96 :       return UNKNOWN_DEFID;
    1148              :     }
    1149              : 
    1150            0 :   return UNKNOWN_DEFID;
    1151              : }
    1152              : 
    1153              : // TypeCheckBlockContextItem
    1154              : 
    1155        11456 : TypeCheckBlockContextItem::Item::Item (HIR::ImplBlock *b) : block (b) {}
    1156              : 
    1157         4242 : TypeCheckBlockContextItem::Item::Item (HIR::Trait *t) : trait (t) {}
    1158              : 
    1159        11456 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::ImplBlock *block)
    1160        11456 :   : type (TypeCheckBlockContextItem::ItemType::IMPL_BLOCK), item (block)
    1161        11456 : {}
    1162              : 
    1163         4242 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::Trait *trait)
    1164         4242 :   : type (TypeCheckBlockContextItem::ItemType::TRAIT), item (trait)
    1165         4242 : {}
    1166              : 
    1167              : bool
    1168            0 : TypeCheckBlockContextItem::is_impl_block () const
    1169              : {
    1170            0 :   return type == IMPL_BLOCK;
    1171              : }
    1172              : 
    1173              : bool
    1174          976 : TypeCheckBlockContextItem::is_trait_block () const
    1175              : {
    1176          976 :   return type == TRAIT;
    1177              : }
    1178              : 
    1179              : HIR::ImplBlock &
    1180          166 : TypeCheckBlockContextItem::get_impl_block ()
    1181              : {
    1182          166 :   return *(item.block);
    1183              : }
    1184              : 
    1185              : HIR::Trait &
    1186          810 : TypeCheckBlockContextItem::get_trait ()
    1187              : {
    1188          810 :   return *(item.trait);
    1189              : }
    1190              : 
    1191              : } // namespace Resolver
    1192              : } // 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.