LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-typecheck-context.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 86.2 % 506 436
Test Date: 2026-10-03 16:17:38 Functions: 88.2 % 102 90
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      7327297 : TypeCheckContext::get ()
      28              : {
      29      7327297 :   static TypeCheckContext *instance;
      30      7327297 :   if (instance == nullptr)
      31         4971 :     instance = new TypeCheckContext ();
      32              : 
      33      7327297 :   return instance;
      34              : }
      35              : 
      36         4971 : 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        36806 : TypeCheckContext::lookup_builtin (std::string name, TyTy::BaseType **type)
      57              : {
      58       418252 :   for (auto &builtin : builtins)
      59              :     {
      60       418252 :       if (name.compare (builtin->as_string ()) == 0)
      61              :         {
      62        36806 :           *type = builtin.get ();
      63        36806 :           return true;
      64              :         }
      65              :     }
      66              :   return false;
      67              : }
      68              : 
      69              : void
      70        95361 : TypeCheckContext::insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type)
      71              : {
      72        95361 :   node_id_refs[ref] = id;
      73        95361 :   resolved[id] = type;
      74        95361 :   builtins.push_back (std::unique_ptr<TyTy::BaseType> (type));
      75        95361 : }
      76              : 
      77              : const std::vector<std::unique_ptr<TyTy::BaseType>> &
      78         4707 : TypeCheckContext::get_builtins () const
      79              : {
      80         4707 :   return builtins;
      81              : }
      82              : 
      83              : void
      84       433805 : TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings,
      85              :                                TyTy::BaseType *type)
      86              : {
      87       433805 :   rust_assert (type != nullptr);
      88       433805 :   NodeId ref = mappings.get_nodeid ();
      89       433805 :   HirId id = mappings.get_hirid ();
      90       433805 :   node_id_refs[ref] = id;
      91       433805 :   resolved[id] = type;
      92       433805 : }
      93              : 
      94              : void
      95       173149 : TypeCheckContext::insert_implicit_type (HirId id, TyTy::BaseType *type)
      96              : {
      97       173149 :   rust_assert (type != nullptr);
      98       173149 :   resolved[id] = type;
      99       173149 : }
     100              : 
     101              : bool
     102      6467339 : TypeCheckContext::lookup_type (HirId id, TyTy::BaseType **type) const
     103              : {
     104      6467339 :   auto it = resolved.find (id);
     105      6467339 :   if (it == resolved.end ())
     106              :     return false;
     107              : 
     108      6251379 :   *type = it->second;
     109      6251379 :   return true;
     110              : }
     111              : 
     112              : void
     113         3079 : TypeCheckContext::mark_function_body_pending (DefId id)
     114              : {
     115         3079 :   function_bodies_pending.insert (id);
     116         3079 : }
     117              : 
     118              : void
     119        15699 : TypeCheckContext::clear_function_body_pending (DefId id)
     120              : {
     121        15699 :   function_bodies_pending.erase (id);
     122        15699 : }
     123              : 
     124              : bool
     125         3087 : TypeCheckContext::function_body_pending (DefId id) const
     126              : {
     127         3087 :   return function_bodies_pending.find (id) != function_bodies_pending.end ();
     128              : }
     129              : 
     130              : void
     131         4710 : TypeCheckContext::clear_type (TyTy::BaseType *ty)
     132              : {
     133         4710 :   auto it = resolved.find (ty->get_ref ());
     134         4710 :   if (it == resolved.end ())
     135         4710 :     return;
     136              : 
     137         4710 :   resolved.erase (it);
     138              : }
     139              : 
     140              : void
     141            0 : TypeCheckContext::insert_type_by_node_id (NodeId ref, HirId id)
     142              : {
     143            0 :   rust_assert (node_id_refs.find (ref) == node_id_refs.end ());
     144            0 :   node_id_refs[ref] = id;
     145            0 : }
     146              : 
     147              : bool
     148            0 : TypeCheckContext::lookup_type_by_node_id (NodeId ref, HirId *id)
     149              : {
     150            0 :   auto it = node_id_refs.find (ref);
     151            0 :   if (it == node_id_refs.end ())
     152              :     return false;
     153              : 
     154            0 :   *id = it->second;
     155            0 :   return true;
     156              : }
     157              : 
     158              : bool
     159        17873 : TypeCheckContext::have_function_context () const
     160              : {
     161        17873 :   return !return_type_stack.empty ();
     162              : }
     163              : 
     164              : TyTy::BaseType *
     165          572 : TypeCheckContext::peek_return_type ()
     166              : {
     167          572 :   rust_assert (!return_type_stack.empty ());
     168          572 :   return return_type_stack.back ().second;
     169              : }
     170              : 
     171              : void
     172        15699 : TypeCheckContext::push_return_type (TypeCheckContextItem item,
     173              :                                     TyTy::BaseType *return_type)
     174              : {
     175        15699 :   return_type_stack.emplace_back (std::move (item), return_type);
     176              :   // a query can check another function body while an expression in the
     177              :   // caller has an expected type
     178        15699 :   push_expected_type (nullptr);
     179        15699 : }
     180              : 
     181              : void
     182        15699 : TypeCheckContext::pop_return_type ()
     183              : {
     184        15699 :   rust_assert (!return_type_stack.empty ());
     185        15699 :   pop_expected_type ();
     186        15699 :   return_type_stack.pop_back ();
     187        15699 : }
     188              : 
     189              : TypeCheckContextItem
     190        17274 : TypeCheckContext::peek_context ()
     191              : {
     192        17274 :   rust_assert (!return_type_stack.empty ());
     193        17274 :   return return_type_stack.back ().first;
     194              : }
     195              : 
     196              : void
     197        71494 : TypeCheckContext::push_expected_type (TyTy::BaseType *expected)
     198              : {
     199        71494 :   expected_type_stack.push_back (expected);
     200        71494 : }
     201              : 
     202              : void
     203        71494 : TypeCheckContext::pop_expected_type ()
     204              : {
     205        71494 :   rust_assert (!expected_type_stack.empty ());
     206        71494 :   expected_type_stack.pop_back ();
     207        71494 : }
     208              : 
     209              : TyTy::BaseType *
     210        36831 : TypeCheckContext::peek_expected_type () const
     211              : {
     212        36831 :   if (expected_type_stack.empty ())
     213              :     return nullptr;
     214        36545 :   return expected_type_stack.back ();
     215              : }
     216              : 
     217              : StackedContexts<TypeCheckBlockContextItem> &
     218        33068 : TypeCheckContext::block_context ()
     219              : {
     220        33068 :   return block_stack;
     221              : }
     222              : 
     223              : void
     224         4505 : TypeCheckContext::iterate (std::function<bool (HirId, TyTy::BaseType *)> cb)
     225              : {
     226       533587 :   for (auto it = resolved.begin (); it != resolved.end (); it++)
     227              :     {
     228       529082 :       if (!cb (it->first, it->second))
     229         4505 :         return;
     230              :     }
     231              : }
     232              : 
     233              : bool
     234          148 : TypeCheckContext::have_loop_context () const
     235              : {
     236          148 :   return !loop_type_stack.empty ();
     237              : }
     238              : 
     239              : void
     240          155 : TypeCheckContext::push_new_loop_context (HirId id, location_t locus)
     241              : {
     242          155 :   TyTy::BaseType *infer_var
     243              :     = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
     244          155 :                            TyTy::InferType::TypeHint::Default (), locus);
     245          155 :   loop_type_stack.push_back (infer_var);
     246          155 : }
     247              : 
     248              : void
     249           94 : TypeCheckContext::push_new_while_loop_context (HirId id)
     250              : {
     251           94 :   TyTy::BaseType *infer_var = new TyTy::ErrorType (id);
     252           94 :   loop_type_stack.push_back (infer_var);
     253           94 : }
     254              : 
     255              : TyTy::BaseType *
     256          274 : TypeCheckContext::peek_loop_context ()
     257              : {
     258          274 :   return loop_type_stack.back ();
     259              : }
     260              : 
     261              : TyTy::BaseType *
     262          249 : TypeCheckContext::pop_loop_context ()
     263              : {
     264          249 :   auto back = peek_loop_context ();
     265          249 :   loop_type_stack.pop_back ();
     266          249 :   return back;
     267              : }
     268              : 
     269              : void
     270           21 : TypeCheckContext::swap_head_loop_context (TyTy::BaseType *val)
     271              : {
     272           21 :   loop_type_stack.pop_back ();
     273           21 :   loop_type_stack.push_back (val);
     274           21 : }
     275              : 
     276              : bool
     277         3884 : TypeCheckContext::find_matching_impl_trait_frame (
     278              :   const TraitReference &tref, TyTy::BaseType &self,
     279              :   struct ImplTraitContextFrame *find) const
     280              : {
     281         3884 :   if (!have_impl_trait_context ())
     282              :     return false;
     283              : 
     284         2879 :   for (auto it = impl_trait_frame_stack.rbegin ();
     285         2879 :        it != impl_trait_frame_stack.rend (); ++it)
     286              :     {
     287         2098 :       const auto &i = *it;
     288         2098 :       if (!i.trait->is_equal (tref))
     289          675 :         continue;
     290              : 
     291         1423 :       TyTy::BaseType *resolved_self = &self;
     292         1423 :       bool unresolved_trait_self = false;
     293         1423 :       if (auto param = self.try_as<TyTy::ParamType> ())
     294              :         {
     295           84 :           if (param->can_resolve ())
     296           84 :             resolved_self = param->resolve ();
     297              :           else
     298            0 :             unresolved_trait_self = param->is_implicit_self_trait ();
     299              :         }
     300              : 
     301           84 :       bool compatible_self
     302              :         = unresolved_trait_self
     303         1423 :           || types_compatable (TyTy::TyWithLocation (i.self),
     304         1423 :                                TyTy::TyWithLocation (resolved_self),
     305              :                                UNDEF_LOCATION, false /* emit_errors */,
     306         1423 :                                false /* check_bounds */);
     307         1423 :       if (compatible_self)
     308              :         {
     309         1290 :           *find = i;
     310         1290 :           return true;
     311              :         }
     312              :     }
     313              : 
     314              :   return false;
     315              : }
     316              : 
     317              : bool
     318         3884 : TypeCheckContext::have_impl_trait_context () const
     319              : {
     320         3884 :   return !impl_trait_frame_stack.empty ();
     321              : }
     322              : 
     323              : void
     324        13507 : TypeCheckContext::push_impl_trait_context (struct ImplTraitContextFrame frame)
     325              : {
     326        13507 :   impl_trait_frame_stack.push_back (frame);
     327        13507 : }
     328              : 
     329              : struct ImplTraitContextFrame
     330        13507 : TypeCheckContext::pop_impl_trait_context ()
     331              : {
     332        13507 :   auto back = peek_impl_trait_context ();
     333        13507 :   impl_trait_frame_stack.pop_back ();
     334        13507 :   return back;
     335              : }
     336              : 
     337              : struct ImplTraitContextFrame
     338        13507 : TypeCheckContext::peek_impl_trait_context ()
     339              : {
     340        13507 :   return impl_trait_frame_stack.back ();
     341              : }
     342              : 
     343              : void
     344         4167 : TypeCheckContext::insert_trait_reference (DefId id, TraitReference &&ref)
     345              : {
     346         4167 :   rust_assert (trait_context.find (id) == trait_context.end ());
     347         4167 :   trait_context.emplace (id, std::move (ref));
     348         4167 : }
     349              : 
     350              : bool
     351       530345 : TypeCheckContext::lookup_trait_reference (DefId id, TraitReference **ref)
     352              : {
     353       530345 :   auto it = trait_context.find (id);
     354       530345 :   if (it == trait_context.end ())
     355              :     return false;
     356              : 
     357       502982 :   *ref = &it->second;
     358       502982 :   return true;
     359              : }
     360              : 
     361              : bool
     362         5335 : TypeCheckContext::insert_associated_trait_impl (
     363              :   HirId id, AssociatedImplTrait &&associated)
     364              : {
     365         5335 :   auto it = associated_impl_traits.find (id);
     366         5335 :   if (it != associated_impl_traits.end ())
     367              :     {
     368              :       return false;
     369              :     }
     370         5334 :   associated_impl_traits.emplace (id, std::move (associated));
     371         5334 :   return true;
     372              : }
     373              : 
     374              : bool
     375        26558 : TypeCheckContext::lookup_associated_trait_impl (
     376              :   HirId id, AssociatedImplTrait **associated)
     377              : {
     378        26558 :   auto it = associated_impl_traits.find (id);
     379        26558 :   if (it == associated_impl_traits.end ())
     380              :     return false;
     381              : 
     382        10578 :   *associated = &it->second;
     383        10578 :   return true;
     384              : }
     385              : 
     386              : void
     387            0 : TypeCheckContext::insert_associated_type_mapping (HirId id, HirId mapping)
     388              : {
     389            0 :   associated_type_mappings[id] = mapping;
     390            0 : }
     391              : 
     392              : void
     393            0 : TypeCheckContext::clear_associated_type_mapping (HirId id)
     394              : {
     395            0 :   auto it = associated_type_mappings.find (id);
     396            0 :   if (it != associated_type_mappings.end ())
     397            0 :     associated_type_mappings.erase (it);
     398            0 : }
     399              : 
     400              : // lookup any associated type mappings, the out parameter of mapping is
     401              : // allowed to be nullptr which allows this interface to do a simple does exist
     402              : // check
     403              : bool
     404            0 : TypeCheckContext::lookup_associated_type_mapping (HirId id, HirId *mapping)
     405              : {
     406            0 :   auto it = associated_type_mappings.find (id);
     407            0 :   if (it == associated_type_mappings.end ())
     408              :     return false;
     409              : 
     410            0 :   if (mapping != nullptr)
     411            0 :     *mapping = it->second;
     412              : 
     413              :   return true;
     414              : }
     415              : 
     416              : void
     417         5335 : TypeCheckContext::insert_associated_impl_mapping (HirId trait_id,
     418              :                                                   TyTy::BaseType *impl_type,
     419              :                                                   HirId impl_id)
     420              : {
     421         5335 :   auto it = associated_traits_to_impls.find (trait_id);
     422         5335 :   if (it == associated_traits_to_impls.end ())
     423              :     {
     424         1956 :       associated_traits_to_impls[trait_id] = {};
     425              :     }
     426              : 
     427         5335 :   associated_traits_to_impls[trait_id].emplace_back (impl_type, impl_id);
     428         5335 : }
     429              : 
     430              : bool
     431            0 : TypeCheckContext::lookup_associated_impl_mapping_for_self (HirId trait_id,
     432              :                                                            TyTy::BaseType *self,
     433              :                                                            HirId *mapping)
     434              : {
     435            0 :   auto it = associated_traits_to_impls.find (trait_id);
     436            0 :   if (it == associated_traits_to_impls.end ())
     437              :     return false;
     438              : 
     439            0 :   for (auto &item : it->second)
     440              :     {
     441            0 :       if (types_compatable (TyTy::TyWithLocation (item.first),
     442            0 :                             TyTy::TyWithLocation (self), UNKNOWN_LOCATION,
     443              :                             false))
     444              :         {
     445            0 :           *mapping = item.second;
     446            0 :           return true;
     447              :         }
     448              :     }
     449              :   return false;
     450              : }
     451              : 
     452              : void
     453        48186 : TypeCheckContext::insert_autoderef_mappings (
     454              :   HirId id, std::vector<Adjustment> &&adjustments)
     455              : {
     456        48186 :   autoderef_mappings.emplace (id, std::move (adjustments));
     457        48186 : }
     458              : 
     459              : bool
     460        51261 : TypeCheckContext::lookup_autoderef_mappings (
     461              :   HirId id, std::vector<Adjustment> **adjustments)
     462              : {
     463        51261 :   auto it = autoderef_mappings.find (id);
     464        51261 :   if (it == autoderef_mappings.end ())
     465              :     return false;
     466              : 
     467        37358 :   *adjustments = &it->second;
     468        37358 :   return true;
     469              : }
     470              : 
     471              : void
     472         5741 : TypeCheckContext::insert_cast_autoderef_mappings (
     473              :   HirId id, std::vector<Adjustment> &&adjustments)
     474              : {
     475         5741 :   cast_autoderef_mappings.emplace (id, std::move (adjustments));
     476         5741 : }
     477              : 
     478              : bool
     479         5380 : TypeCheckContext::lookup_cast_autoderef_mappings (
     480              :   HirId id, std::vector<Adjustment> **adjustments)
     481              : {
     482         5380 :   auto it = cast_autoderef_mappings.find (id);
     483         5380 :   if (it == cast_autoderef_mappings.end ())
     484              :     return false;
     485              : 
     486         5380 :   *adjustments = &it->second;
     487         5380 :   return true;
     488              : }
     489              : 
     490              : void
     491         4496 : TypeCheckContext::insert_variant_definition (HirId id, HirId variant)
     492              : {
     493         4496 :   auto it = variants.find (id);
     494         4496 :   rust_assert (it == variants.end ());
     495              : 
     496         4496 :   variants[id] = variant;
     497         4496 : }
     498              : 
     499              : bool
     500         8751 : TypeCheckContext::lookup_variant_definition (HirId id, HirId *variant)
     501              : {
     502         8751 :   auto it = variants.find (id);
     503         8751 :   if (it == variants.end ())
     504              :     return false;
     505              : 
     506         8745 :   *variant = it->second;
     507         8745 :   return true;
     508              : }
     509              : 
     510              : void
     511         1408 : TypeCheckContext::insert_operator_overload (HirId id, TyTy::FnType *call_site)
     512              : {
     513         1408 :   auto it = operator_overloads.find (id);
     514         1408 :   rust_assert (it == operator_overloads.end ());
     515              : 
     516         1408 :   operator_overloads[id] = call_site;
     517         1408 : }
     518              : 
     519              : bool
     520        25266 : TypeCheckContext::lookup_operator_overload (HirId id, TyTy::FnType **call)
     521              : {
     522        25266 :   auto it = operator_overloads.find (id);
     523        25266 :   if (it == operator_overloads.end ())
     524              :     return false;
     525              : 
     526         2498 :   *call = it->second;
     527         2498 :   return true;
     528              : }
     529              : 
     530              : void
     531           15 : TypeCheckContext::insert_deferred_operator_overload (
     532              :   DeferredOpOverload deferred)
     533              : {
     534           15 :   HirId expr_id = deferred.expr_id;
     535           15 :   deferred_operator_overloads.emplace (std::make_pair (expr_id, deferred));
     536           15 : }
     537              : 
     538              : bool
     539            0 : TypeCheckContext::lookup_deferred_operator_overload (
     540              :   HirId id, DeferredOpOverload *deferred)
     541              : {
     542            0 :   auto it = deferred_operator_overloads.find (id);
     543            0 :   if (it == deferred_operator_overloads.end ())
     544              :     return false;
     545              : 
     546            0 :   *deferred = it->second;
     547            0 :   return true;
     548              : }
     549              : 
     550              : void
     551            0 : TypeCheckContext::iterate_deferred_operator_overloads (
     552              :   std::function<bool (HirId, DeferredOpOverload &)> cb)
     553              : {
     554            0 :   for (auto it = deferred_operator_overloads.begin ();
     555            0 :        it != deferred_operator_overloads.end (); it++)
     556              :     {
     557            0 :       if (!cb (it->first, it->second))
     558            0 :         return;
     559              :     }
     560              : }
     561              : 
     562              : void
     563         6432 : TypeCheckContext::insert_unconstrained_check_marker (HirId id, bool status)
     564              : {
     565         6432 :   unconstrained[id] = status;
     566         6432 : }
     567              : 
     568              : bool
     569        34858 : TypeCheckContext::have_checked_for_unconstrained (HirId id, bool *result)
     570              : {
     571        34858 :   auto it = unconstrained.find (id);
     572        34858 :   bool found = it != unconstrained.end ();
     573        34858 :   if (!found)
     574              :     return false;
     575              : 
     576        28426 :   *result = it->second;
     577        28426 :   return true;
     578              : }
     579              : 
     580              : void
     581         7904 : TypeCheckContext::insert_resolved_predicate (
     582              :   HirId id, const TyTy::TypeBoundPredicate &predicate)
     583              : {
     584              :   // auto it = predicates.find (id);
     585              :   // rust_assert (it == predicates.end ());
     586              : 
     587         7904 :   predicates.emplace (id, predicate);
     588         7904 : }
     589              : 
     590              : bool
     591        34087 : TypeCheckContext::lookup_predicate (HirId id, TyTy::TypeBoundPredicate *result)
     592              : {
     593        34087 :   auto it = predicates.find (id);
     594        34087 :   bool found = it != predicates.end ();
     595        34087 :   if (!found)
     596              :     return false;
     597              : 
     598        25843 :   *result = it->second;
     599        25843 :   return true;
     600              : }
     601              : 
     602              : void
     603         7993 : TypeCheckContext::insert_query (HirId id)
     604              : {
     605         7993 :   querys_in_progress.insert (id);
     606         7993 : }
     607              : 
     608              : void
     609         7993 : TypeCheckContext::query_completed (HirId id)
     610              : {
     611         7993 :   querys_in_progress.erase (id);
     612         7993 : }
     613              : 
     614              : bool
     615         8436 : TypeCheckContext::query_in_progress (HirId id) const
     616              : {
     617         8436 :   return querys_in_progress.find (id) != querys_in_progress.end ();
     618              : }
     619              : 
     620              : void
     621         4182 : TypeCheckContext::insert_trait_query (DefId id)
     622              : {
     623         4182 :   trait_queries_in_progress.insert (id);
     624         4182 : }
     625              : 
     626              : void
     627         4182 : TypeCheckContext::trait_query_completed (DefId id)
     628              : {
     629         4182 :   trait_queries_in_progress.erase (id);
     630         4182 : }
     631              : 
     632              : bool
     633         4186 : TypeCheckContext::trait_query_in_progress (DefId id) const
     634              : {
     635         4186 :   return trait_queries_in_progress.find (id)
     636         4186 :          != trait_queries_in_progress.end ();
     637              : }
     638              : 
     639              : Lifetime
     640          901 : TypeCheckContext::intern_lifetime (const HIR::Lifetime &lifetime)
     641              : {
     642          901 :   if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
     643              :     {
     644          900 :       auto maybe_interned = lookup_lifetime (lifetime);
     645          900 :       if (maybe_interned)
     646          800 :         return *maybe_interned;
     647              : 
     648          100 :       auto interned = next_lifetime_index.next ();
     649          100 :       lifetime_name_interner[lifetime.get_name ()] = interned;
     650          100 :       return interned;
     651              :     }
     652            1 :   if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
     653              :     {
     654            1 :       return next_lifetime_index.next ();
     655              :     }
     656            0 :   if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
     657              :     {
     658            0 :       return Lifetime::static_lifetime ();
     659              :     }
     660            0 :   rust_unreachable ();
     661              : }
     662              : 
     663              : tl::optional<Lifetime>
     664        10707 : TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const
     665              : {
     666        10707 :   if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
     667              :     {
     668         1188 :       if (lifetime.get_name () == "static")
     669              :         {
     670            1 :           rich_location r (line_table, lifetime.get_locus ());
     671            1 :           r.add_fixit_insert_after (lifetime.get_locus (),
     672              :                                     "static is a reserved lifetime name");
     673            1 :           rust_error_at (r, ErrorCode::E0262,
     674              :                          "invalid lifetime parameter name: %qs",
     675            1 :                          lifetime.get_name ().c_str ());
     676            1 :           return tl::nullopt;
     677            1 :         }
     678         1187 :       const auto name = lifetime.get_name ();
     679         1187 :       auto it = lifetime_name_interner.find (name);
     680         1187 :       if (it == lifetime_name_interner.end ())
     681          104 :         return tl::nullopt;
     682         1083 :       return it->second;
     683         1187 :     }
     684         9519 :   if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
     685              :     {
     686         9428 :       return Lifetime::anonymous_lifetime ();
     687              :     }
     688           91 :   if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
     689              :     {
     690           91 :       return Lifetime::static_lifetime ();
     691              :     }
     692            0 :   rust_unreachable ();
     693              : }
     694              : 
     695              : WARN_UNUSED_RESULT tl::optional<TyTy::Region>
     696         9807 : TypeCheckContext::lookup_and_resolve_lifetime (
     697              :   const HIR::Lifetime &lifetime) const
     698              : {
     699         9807 :   auto maybe_interned = lookup_lifetime (lifetime);
     700         9807 :   if (!maybe_interned)
     701            5 :     return tl::nullopt;
     702              : 
     703         9802 :   return get_lifetime_resolver ().resolve (maybe_interned.value ());
     704              : }
     705              : void
     706           32 : TypeCheckContext::intern_and_insert_lifetime (const HIR::Lifetime &lifetime)
     707              : {
     708           32 :   get_lifetime_resolver ().insert_mapping (intern_lifetime (lifetime));
     709           32 : }
     710              : 
     711              : WARN_UNUSED_RESULT std::vector<TyTy::Region>
     712        10954 : TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
     713              : {
     714        10954 :   std::vector<TyTy::Region> regions;
     715        10983 :   for (const auto &lifetime : args.get_lifetime_args ())
     716              :     {
     717           30 :       auto resolved = lookup_and_resolve_lifetime (lifetime);
     718           30 :       if (!resolved)
     719              :         {
     720            1 :           rust_error_at (lifetime.get_locus (), "unresolved lifetime");
     721            1 :           return {};
     722              :         }
     723           29 :       regions.push_back (*resolved);
     724              :     }
     725        10953 :   return regions;
     726        10954 : }
     727              : 
     728              : bool
     729           15 : TypeCheckContext::compute_ambigious_op_overload (HirId id,
     730              :                                                  DeferredOpOverload &op)
     731              : {
     732           15 :   rust_debug ("attempting resolution of deferred operator overload");
     733              : 
     734           15 :   TyTy::BaseType *lhs = nullptr;
     735           15 :   bool ok = lookup_type (op.op.get_lvalue_mappings ().get_hirid (), &lhs);
     736           15 :   rust_assert (ok);
     737              : 
     738           15 :   TyTy::BaseType *rhs = nullptr;
     739           15 :   if (op.op.has_rvalue_mappings ())
     740              :     {
     741           15 :       bool ok = lookup_type (op.op.get_rvalue_mappings ().get_hirid (), &rhs);
     742           15 :       rust_assert (ok);
     743              :     }
     744              : 
     745           15 :   TyTy::BaseType *current_result = op.result_type.get_tyty ();
     746           15 :   rust_assert (current_result != nullptr);
     747              : 
     748           15 :   rust_debug ("deferred operator expr=%u lhs=%s rhs=%s "
     749              :               "stored-result=%s current-result=%s result-ref=%u ty-ref=%u",
     750              :               id, lhs->debug_str ().c_str (),
     751              :               rhs == nullptr ? "<none>" : rhs->debug_str ().c_str (),
     752              :               current_result->debug_str ().c_str (),
     753              :               current_result->debug_str ().c_str (), op.result_type.get_ref (),
     754              :               current_result->get_ty_ref ());
     755              : 
     756           15 :   TyTy::BaseType *resolved
     757           15 :     = TypeCheckExpr::ResolveOpOverload (op.lang_item_type, op.op, lhs, rhs,
     758           15 :                                         op.specified_segment, current_result);
     759           15 :   if (resolved == nullptr)
     760              :     return false;
     761              : 
     762           15 :   TyTy::BaseType *result
     763           15 :     = unify_site (id, TyTy::TyWithLocation (current_result),
     764           15 :                   TyTy::TyWithLocation (resolved), op.op.get_locus ());
     765           15 :   rust_assert (result != nullptr);
     766           15 :   rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
     767              : 
     768              :   return true;
     769              : }
     770              : 
     771              : void
     772         4505 : TypeCheckContext::compute_inference_variables (bool emit_error)
     773              : {
     774         9010 :   auto resolve_deferred_operator_overloads = [this] () {
     775         9025 :     bool progress;
     776         9025 :     do
     777              :       {
     778         9025 :         progress = false;
     779         9025 :         for (auto it = deferred_operator_overloads.begin ();
     780         9040 :              it != deferred_operator_overloads.end ();)
     781              :           {
     782           15 :             if (compute_ambigious_op_overload (it->first, it->second))
     783              :               {
     784           15 :                 it = deferred_operator_overloads.erase (it);
     785           15 :                 progress = true;
     786              :               }
     787              :             else
     788            0 :               ++it;
     789              :           }
     790              :       }
     791              :     while (progress);
     792        13515 :   };
     793              : 
     794         4505 :   resolve_deferred_operator_overloads ();
     795              : 
     796         4505 :   iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
     797       529082 :     return compute_infer_var (id, ty, emit_error);
     798              :   });
     799              : 
     800         4505 :   resolve_deferred_operator_overloads ();
     801         4505 : }
     802              : 
     803              : bool
     804       529082 : TypeCheckContext::compute_infer_var (HirId id, TyTy::BaseType *ty,
     805              :                                      bool emit_error)
     806              : {
     807       529082 :   auto &mappings = Analysis::Mappings::get ();
     808              : 
     809              :   // nothing to do
     810       529082 :   if (ty->get_kind () != TyTy::TypeKind::INFER)
     811              :     return true;
     812              : 
     813         1593 :   TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
     814         1593 :   TyTy::BaseType *default_type;
     815              : 
     816         1593 :   TyTy::BaseType *current = TyTy::TyVar (ty->get_ref ()).get_tyty ();
     817         1593 :   rust_assert (current != nullptr);
     818              : 
     819         1593 :   rust_debug_loc (mappings.lookup_location (id),
     820              :                   "trying to default infer-var id=%u ref=%u ty-ref=%u "
     821              :                   "stored=%s current=%s",
     822              :                   id, ty->get_ref (), ty->get_ty_ref (),
     823              :                   infer_var->debug_str ().c_str (),
     824              :                   current->debug_str ().c_str ());
     825         1593 :   bool ok = infer_var->default_type (&default_type);
     826         1593 :   if (!ok)
     827              :     {
     828            8 :       if (emit_error)
     829            8 :         rust_error_at (mappings.lookup_location (id), ErrorCode::E0282,
     830              :                        "type annotations needed");
     831              :       return true;
     832              :     }
     833              : 
     834         1585 :   rust_debug_loc (mappings.lookup_location (id), "default type selected: %s",
     835              :                   default_type->debug_str ().c_str ());
     836              : 
     837         1585 :   auto result
     838         1585 :     = unify_site (id, TyTy::TyWithLocation (ty),
     839         1585 :                   TyTy::TyWithLocation (default_type), UNDEF_LOCATION);
     840         1585 :   rust_assert (result);
     841         1585 :   rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
     842         1585 :   result->set_ref (id);
     843         1585 :   insert_implicit_type (id, result);
     844              : 
     845         1585 :   return true;
     846              : }
     847              : 
     848              : TyTy::VarianceAnalysis::CrateCtx &
     849         8974 : TypeCheckContext::get_variance_analysis_ctx ()
     850              : {
     851         8974 :   return variance_analysis_ctx;
     852              : }
     853              : 
     854              : // TypeCheckContextItem
     855              : 
     856        10117 : TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
     857              : 
     858         7891 : TypeCheckContextItem::Item::Item (HIR::ImplBlock *impl_block,
     859              :                                   HIR::Function *item)
     860         7891 :   : impl_item ({impl_block, item})
     861         7891 : {}
     862              : 
     863          869 : TypeCheckContextItem::Item::Item (HIR::TraitItemFunc *trait_item)
     864          869 :   : trait_item (trait_item)
     865          869 : {}
     866              : 
     867         6939 : TypeCheckContextItem::TypeCheckContextItem (HIR::Function *item)
     868         6939 :   : type (ItemType::ITEM), item (item)
     869         6939 : {}
     870              : 
     871         7891 : TypeCheckContextItem::TypeCheckContextItem (HIR::ImplBlock &impl_block,
     872              :                                             HIR::Function *item)
     873         7891 :   : type (ItemType::IMPL_ITEM), item (&impl_block, item)
     874         7891 : {}
     875              : 
     876          869 : TypeCheckContextItem::TypeCheckContextItem (HIR::TraitItemFunc *trait_item)
     877          869 :   : type (ItemType::TRAIT_ITEM), item (trait_item)
     878          869 : {}
     879              : 
     880        33056 : TypeCheckContextItem::TypeCheckContextItem (const TypeCheckContextItem &other)
     881        33056 :   : type (other.type), item (other.item)
     882              : {
     883        33056 :   switch (other.type)
     884              :     {
     885        15308 :     case ITEM:
     886        15308 :       item.item = other.item.item;
     887        15308 :       break;
     888              : 
     889        16315 :     case IMPL_ITEM:
     890        16315 :       item.impl_item = other.item.impl_item;
     891        16315 :       break;
     892              : 
     893         1433 :     case TRAIT_ITEM:
     894         1433 :       item.trait_item = other.item.trait_item;
     895         1433 :       break;
     896              : 
     897            0 :     case ERROR:
     898            0 :       item.item = nullptr;
     899            0 :       break;
     900              :     }
     901        33056 : }
     902              : 
     903         3178 : TypeCheckContextItem::TypeCheckContextItem ()
     904         3178 :   : type (ItemType::ERROR), item (static_cast<HIR::Function *> (nullptr))
     905         3178 : {}
     906              : 
     907              : TypeCheckContextItem &
     908         3163 : TypeCheckContextItem::operator= (const TypeCheckContextItem &other)
     909              : {
     910         3163 :   type = other.type;
     911         3163 :   switch (other.type)
     912              :     {
     913          700 :     case ITEM:
     914          700 :       item.item = other.item.item;
     915          700 :       break;
     916              : 
     917         2349 :     case IMPL_ITEM:
     918         2349 :       item.impl_item = other.item.impl_item;
     919         2349 :       break;
     920              : 
     921          114 :     case TRAIT_ITEM:
     922          114 :       item.trait_item = other.item.trait_item;
     923          114 :       break;
     924              : 
     925            0 :     case ERROR:
     926            0 :       item.item = nullptr;
     927            0 :       break;
     928              :     }
     929              : 
     930         3163 :   return *this;
     931              : }
     932              : 
     933              : TypeCheckContextItem
     934         3178 : TypeCheckContextItem::get_error ()
     935              : {
     936         3178 :   return TypeCheckContextItem ();
     937              : }
     938              : 
     939              : bool
     940            0 : TypeCheckContextItem::is_error () const
     941              : {
     942            0 :   return type == ERROR;
     943              : }
     944              : 
     945              : HIR::Function *
     946           63 : TypeCheckContextItem::get_item ()
     947              : {
     948           63 :   rust_assert (get_type () == ItemType::ITEM);
     949           63 :   return item.item;
     950              : }
     951              : 
     952              : std::pair<HIR::ImplBlock *, HIR::Function *> &
     953          781 : TypeCheckContextItem::get_impl_item ()
     954              : {
     955          781 :   rust_assert (get_type () == ItemType::IMPL_ITEM);
     956          781 :   return item.impl_item;
     957              : }
     958              : 
     959              : HIR::TraitItemFunc *
     960            1 : TypeCheckContextItem::get_trait_item ()
     961              : {
     962            1 :   rust_assert (get_type () == ItemType::TRAIT_ITEM);
     963            1 :   return item.trait_item;
     964              : }
     965              : 
     966              : TypeCheckContextItem::ItemType
     967        19959 : TypeCheckContextItem::get_type () const
     968              : {
     969        19959 :   return type;
     970              : }
     971              : 
     972              : TyTy::FnType *
     973           64 : TypeCheckContextItem::get_context_type ()
     974              : {
     975           64 :   auto &context = *TypeCheckContext::get ();
     976              : 
     977           64 :   HirId reference = UNKNOWN_HIRID;
     978           64 :   switch (get_type ())
     979              :     {
     980           63 :     case ITEM:
     981           63 :       reference = get_item ()->get_mappings ().get_hirid ();
     982           63 :       break;
     983              : 
     984            0 :     case IMPL_ITEM:
     985            0 :       reference = get_impl_item ().second->get_mappings ().get_hirid ();
     986            0 :       break;
     987              : 
     988            1 :     case TRAIT_ITEM:
     989            1 :       reference = get_trait_item ()->get_mappings ().get_hirid ();
     990            1 :       break;
     991              : 
     992            0 :     case ERROR:
     993            0 :       rust_unreachable ();
     994              :       return nullptr;
     995              :     }
     996              : 
     997           64 :   rust_assert (reference != UNKNOWN_HIRID);
     998              : 
     999           64 :   TyTy::BaseType *lookup = nullptr;
    1000           64 :   bool ok = context.lookup_type (reference, &lookup);
    1001           64 :   rust_assert (ok);
    1002           64 :   rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
    1003           64 :   return static_cast<TyTy::FnType *> (lookup);
    1004              : }
    1005              : 
    1006              : DefId
    1007         3432 : TypeCheckContextItem::get_defid () const
    1008              : {
    1009         3432 :   switch (get_type ())
    1010              :     {
    1011          952 :     case ITEM:
    1012          952 :       return item.item->get_mappings ().get_defid ();
    1013              : 
    1014         2270 :     case IMPL_ITEM:
    1015         2270 :       return item.impl_item.second->get_mappings ().get_defid ();
    1016              : 
    1017          114 :     case TRAIT_ITEM:
    1018          114 :       return item.trait_item->get_mappings ().get_defid ();
    1019              : 
    1020           96 :     case ERROR:
    1021           96 :       return UNKNOWN_DEFID;
    1022              :     }
    1023              : 
    1024            0 :   return UNKNOWN_DEFID;
    1025              : }
    1026              : 
    1027              : // TypeCheckBlockContextItem
    1028              : 
    1029        11408 : TypeCheckBlockContextItem::Item::Item (HIR::ImplBlock *b) : block (b) {}
    1030              : 
    1031         4167 : TypeCheckBlockContextItem::Item::Item (HIR::Trait *t) : trait (t) {}
    1032              : 
    1033        11408 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::ImplBlock *block)
    1034        11408 :   : type (TypeCheckBlockContextItem::ItemType::IMPL_BLOCK), item (block)
    1035        11408 : {}
    1036              : 
    1037         4167 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::Trait *trait)
    1038         4167 :   : type (TypeCheckBlockContextItem::ItemType::TRAIT), item (trait)
    1039         4167 : {}
    1040              : 
    1041              : bool
    1042            0 : TypeCheckBlockContextItem::is_impl_block () const
    1043              : {
    1044            0 :   return type == IMPL_BLOCK;
    1045              : }
    1046              : 
    1047              : bool
    1048          959 : TypeCheckBlockContextItem::is_trait_block () const
    1049              : {
    1050          959 :   return type == TRAIT;
    1051              : }
    1052              : 
    1053              : HIR::ImplBlock &
    1054          166 : TypeCheckBlockContextItem::get_impl_block ()
    1055              : {
    1056          166 :   return *(item.block);
    1057              : }
    1058              : 
    1059              : HIR::Trait &
    1060          793 : TypeCheckBlockContextItem::get_trait ()
    1061              : {
    1062          793 :   return *(item.trait);
    1063              : }
    1064              : 
    1065              : } // namespace Resolver
    1066              : } // namespace Rust
        

Generated by: LCOV version 2.4-beta

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