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.3 % 459 396
Test Date: 2026-07-11 15:47:05 Functions: 88.8 % 98 87
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     26293946 : TypeCheckContext::get ()
      28              : {
      29     26293946 :   static TypeCheckContext *instance;
      30     26293946 :   if (instance == nullptr)
      31         4767 :     instance = new TypeCheckContext ();
      32              : 
      33     26293946 :   return instance;
      34              : }
      35              : 
      36         4767 : 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        35401 : TypeCheckContext::lookup_builtin (std::string name, TyTy::BaseType **type)
      57              : {
      58       401401 :   for (auto &builtin : builtins)
      59              :     {
      60       401401 :       if (name.compare (builtin->as_string ()) == 0)
      61              :         {
      62        35401 :           *type = builtin.get ();
      63        35401 :           return true;
      64              :         }
      65              :     }
      66              :   return false;
      67              : }
      68              : 
      69              : void
      70        90573 : TypeCheckContext::insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type)
      71              : {
      72        90573 :   node_id_refs[ref] = id;
      73        90573 :   resolved[id] = type;
      74        90573 :   builtins.push_back (std::unique_ptr<TyTy::BaseType> (type));
      75        90573 : }
      76              : 
      77              : const std::vector<std::unique_ptr<TyTy::BaseType>> &
      78         4538 : TypeCheckContext::get_builtins () const
      79              : {
      80         4538 :   return builtins;
      81              : }
      82              : 
      83              : void
      84       488919 : TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings,
      85              :                                TyTy::BaseType *type)
      86              : {
      87       488919 :   rust_assert (type != nullptr);
      88       488919 :   NodeId ref = mappings.get_nodeid ();
      89       488919 :   HirId id = mappings.get_hirid ();
      90       488919 :   node_id_refs[ref] = id;
      91       488919 :   resolved[id] = type;
      92       488919 : }
      93              : 
      94              : void
      95       288058 : TypeCheckContext::insert_implicit_type (HirId id, TyTy::BaseType *type)
      96              : {
      97       288058 :   rust_assert (type != nullptr);
      98       288058 :   resolved[id] = type;
      99       288058 : }
     100              : 
     101              : bool
     102     18823457 : TypeCheckContext::lookup_type (HirId id, TyTy::BaseType **type) const
     103              : {
     104     18823457 :   auto it = resolved.find (id);
     105     18823457 :   if (it == resolved.end ())
     106              :     return false;
     107              : 
     108     18622453 :   *type = it->second;
     109     18622453 :   return true;
     110              : }
     111              : 
     112              : void
     113       127124 : TypeCheckContext::clear_type (TyTy::BaseType *ty)
     114              : {
     115       127124 :   auto it = resolved.find (ty->get_ref ());
     116       127124 :   if (it == resolved.end ())
     117       127124 :     return;
     118              : 
     119       127124 :   resolved.erase (it);
     120              : }
     121              : 
     122              : void
     123            0 : TypeCheckContext::insert_type_by_node_id (NodeId ref, HirId id)
     124              : {
     125            0 :   rust_assert (node_id_refs.find (ref) == node_id_refs.end ());
     126            0 :   node_id_refs[ref] = id;
     127            0 : }
     128              : 
     129              : bool
     130            0 : TypeCheckContext::lookup_type_by_node_id (NodeId ref, HirId *id)
     131              : {
     132            0 :   auto it = node_id_refs.find (ref);
     133            0 :   if (it == node_id_refs.end ())
     134              :     return false;
     135              : 
     136            0 :   *id = it->second;
     137            0 :   return true;
     138              : }
     139              : 
     140              : bool
     141         3413 : TypeCheckContext::have_function_context () const
     142              : {
     143         3413 :   return !return_type_stack.empty ();
     144              : }
     145              : 
     146              : TyTy::BaseType *
     147          530 : TypeCheckContext::peek_return_type ()
     148              : {
     149          530 :   rust_assert (!return_type_stack.empty ());
     150          530 :   return return_type_stack.back ().second;
     151              : }
     152              : 
     153              : void
     154        14363 : TypeCheckContext::push_return_type (TypeCheckContextItem item,
     155              :                                     TyTy::BaseType *return_type)
     156              : {
     157        14363 :   return_type_stack.emplace_back (std::move (item), return_type);
     158        14363 : }
     159              : 
     160              : void
     161        14363 : TypeCheckContext::pop_return_type ()
     162              : {
     163        14363 :   rust_assert (!return_type_stack.empty ());
     164        14363 :   return_type_stack.pop_back ();
     165        14363 : }
     166              : 
     167              : TypeCheckContextItem
     168         2873 : TypeCheckContext::peek_context ()
     169              : {
     170         2873 :   rust_assert (!return_type_stack.empty ());
     171         2873 :   return return_type_stack.back ().first;
     172              : }
     173              : 
     174              : void
     175        50820 : TypeCheckContext::push_expected_type (TyTy::BaseType *expected)
     176              : {
     177        50820 :   expected_type_stack.push_back (expected);
     178        50820 : }
     179              : 
     180              : void
     181        50820 : TypeCheckContext::pop_expected_type ()
     182              : {
     183        50820 :   rust_assert (!expected_type_stack.empty ());
     184        50820 :   expected_type_stack.pop_back ();
     185        50820 : }
     186              : 
     187              : TyTy::BaseType *
     188        33863 : TypeCheckContext::peek_expected_type () const
     189              : {
     190        33863 :   if (expected_type_stack.empty ())
     191              :     return nullptr;
     192        23015 :   return expected_type_stack.back ();
     193              : }
     194              : 
     195              : StackedContexts<TypeCheckBlockContextItem> &
     196        25976 : TypeCheckContext::block_context ()
     197              : {
     198        25976 :   return block_stack;
     199              : }
     200              : 
     201              : void
     202         4346 : TypeCheckContext::iterate (std::function<bool (HirId, TyTy::BaseType *)> cb)
     203              : {
     204       504698 :   for (auto it = resolved.begin (); it != resolved.end (); it++)
     205              :     {
     206       500352 :       if (!cb (it->first, it->second))
     207         4346 :         return;
     208              :     }
     209              : }
     210              : 
     211              : bool
     212          107 : TypeCheckContext::have_loop_context () const
     213              : {
     214          107 :   return !loop_type_stack.empty ();
     215              : }
     216              : 
     217              : void
     218          130 : TypeCheckContext::push_new_loop_context (HirId id, location_t locus)
     219              : {
     220          130 :   TyTy::BaseType *infer_var
     221              :     = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
     222          130 :                            TyTy::InferType::TypeHint::Default (), locus);
     223          130 :   loop_type_stack.push_back (infer_var);
     224          130 : }
     225              : 
     226              : void
     227           78 : TypeCheckContext::push_new_while_loop_context (HirId id)
     228              : {
     229           78 :   TyTy::BaseType *infer_var = new TyTy::ErrorType (id);
     230           78 :   loop_type_stack.push_back (infer_var);
     231           78 : }
     232              : 
     233              : TyTy::BaseType *
     234          231 : TypeCheckContext::peek_loop_context ()
     235              : {
     236          231 :   return loop_type_stack.back ();
     237              : }
     238              : 
     239              : TyTy::BaseType *
     240          208 : TypeCheckContext::pop_loop_context ()
     241              : {
     242          208 :   auto back = peek_loop_context ();
     243          208 :   loop_type_stack.pop_back ();
     244          208 :   return back;
     245              : }
     246              : 
     247              : void
     248           19 : TypeCheckContext::swap_head_loop_context (TyTy::BaseType *val)
     249              : {
     250           19 :   loop_type_stack.pop_back ();
     251           19 :   loop_type_stack.push_back (val);
     252           19 : }
     253              : 
     254              : bool
     255        11109 : TypeCheckContext::find_matching_impl_trait_frame (
     256              :   const TraitReference &tref, struct ImplTraitContextFrame *find) const
     257              : {
     258        11109 :   if (!have_impl_trait_context ())
     259              :     return false;
     260              : 
     261         5814 :   for (auto it = impl_trait_frame_stack.rbegin ();
     262         5814 :        it != impl_trait_frame_stack.rend (); ++it)
     263              :     {
     264         5134 :       const auto &i = *it;
     265         5134 :       if (i.trait->is_equal (tref))
     266              :         {
     267         4450 :           *find = i;
     268         4450 :           return true;
     269              :         }
     270              :     }
     271              : 
     272              :   return false;
     273              : }
     274              : 
     275              : bool
     276        11109 : TypeCheckContext::have_impl_trait_context () const
     277              : {
     278        11109 :   return !impl_trait_frame_stack.empty ();
     279              : }
     280              : 
     281              : void
     282        13326 : TypeCheckContext::push_impl_trait_context (struct ImplTraitContextFrame frame)
     283              : {
     284        13326 :   impl_trait_frame_stack.push_back (frame);
     285        13326 : }
     286              : 
     287              : struct ImplTraitContextFrame
     288        13326 : TypeCheckContext::pop_impl_trait_context ()
     289              : {
     290        13326 :   auto back = peek_impl_trait_context ();
     291        13326 :   impl_trait_frame_stack.pop_back ();
     292        13326 :   return back;
     293              : }
     294              : 
     295              : struct ImplTraitContextFrame
     296        13326 : TypeCheckContext::peek_impl_trait_context ()
     297              : {
     298        13326 :   return impl_trait_frame_stack.back ();
     299              : }
     300              : 
     301              : void
     302         3915 : TypeCheckContext::insert_trait_reference (DefId id, TraitReference &&ref)
     303              : {
     304         3915 :   rust_assert (trait_context.find (id) == trait_context.end ());
     305         3915 :   trait_context.emplace (id, std::move (ref));
     306         3915 : }
     307              : 
     308              : bool
     309      1197955 : TypeCheckContext::lookup_trait_reference (DefId id, TraitReference **ref)
     310              : {
     311      1197955 :   auto it = trait_context.find (id);
     312      1197955 :   if (it == trait_context.end ())
     313              :     return false;
     314              : 
     315      1172428 :   *ref = &it->second;
     316      1172428 :   return true;
     317              : }
     318              : 
     319              : bool
     320         4719 : TypeCheckContext::insert_associated_trait_impl (
     321              :   HirId id, AssociatedImplTrait &&associated)
     322              : {
     323         4719 :   auto it = associated_impl_traits.find (id);
     324         4719 :   if (it != associated_impl_traits.end ())
     325              :     {
     326              :       return false;
     327              :     }
     328         4718 :   associated_impl_traits.emplace (id, std::move (associated));
     329         4718 :   return true;
     330              : }
     331              : 
     332              : bool
     333        50761 : TypeCheckContext::lookup_associated_trait_impl (
     334              :   HirId id, AssociatedImplTrait **associated)
     335              : {
     336        50761 :   auto it = associated_impl_traits.find (id);
     337        50761 :   if (it == associated_impl_traits.end ())
     338              :     return false;
     339              : 
     340        27013 :   *associated = &it->second;
     341        27013 :   return true;
     342              : }
     343              : 
     344              : void
     345            0 : TypeCheckContext::insert_associated_type_mapping (HirId id, HirId mapping)
     346              : {
     347            0 :   associated_type_mappings[id] = mapping;
     348            0 : }
     349              : 
     350              : void
     351            0 : TypeCheckContext::clear_associated_type_mapping (HirId id)
     352              : {
     353            0 :   auto it = associated_type_mappings.find (id);
     354            0 :   if (it != associated_type_mappings.end ())
     355            0 :     associated_type_mappings.erase (it);
     356            0 : }
     357              : 
     358              : // lookup any associated type mappings, the out parameter of mapping is
     359              : // allowed to be nullptr which allows this interface to do a simple does exist
     360              : // check
     361              : bool
     362            0 : TypeCheckContext::lookup_associated_type_mapping (HirId id, HirId *mapping)
     363              : {
     364            0 :   auto it = associated_type_mappings.find (id);
     365            0 :   if (it == associated_type_mappings.end ())
     366              :     return false;
     367              : 
     368            0 :   if (mapping != nullptr)
     369            0 :     *mapping = it->second;
     370              : 
     371              :   return true;
     372              : }
     373              : 
     374              : void
     375         4719 : TypeCheckContext::insert_associated_impl_mapping (HirId trait_id,
     376              :                                                   TyTy::BaseType *impl_type,
     377              :                                                   HirId impl_id)
     378              : {
     379         4719 :   auto it = associated_traits_to_impls.find (trait_id);
     380         4719 :   if (it == associated_traits_to_impls.end ())
     381              :     {
     382         1824 :       associated_traits_to_impls[trait_id] = {};
     383              :     }
     384              : 
     385         4719 :   associated_traits_to_impls[trait_id].emplace_back (impl_type, impl_id);
     386         4719 : }
     387              : 
     388              : bool
     389            0 : TypeCheckContext::lookup_associated_impl_mapping_for_self (HirId trait_id,
     390              :                                                            TyTy::BaseType *self,
     391              :                                                            HirId *mapping)
     392              : {
     393            0 :   auto it = associated_traits_to_impls.find (trait_id);
     394            0 :   if (it == associated_traits_to_impls.end ())
     395              :     return false;
     396              : 
     397            0 :   for (auto &item : it->second)
     398              :     {
     399            0 :       if (types_compatable (TyTy::TyWithLocation (item.first),
     400            0 :                             TyTy::TyWithLocation (self), UNKNOWN_LOCATION,
     401              :                             false))
     402              :         {
     403            0 :           *mapping = item.second;
     404            0 :           return true;
     405              :         }
     406              :     }
     407              :   return false;
     408              : }
     409              : 
     410              : void
     411        44876 : TypeCheckContext::insert_autoderef_mappings (
     412              :   HirId id, std::vector<Adjustment> &&adjustments)
     413              : {
     414        44876 :   autoderef_mappings.emplace (id, std::move (adjustments));
     415        44876 : }
     416              : 
     417              : bool
     418        47983 : TypeCheckContext::lookup_autoderef_mappings (
     419              :   HirId id, std::vector<Adjustment> **adjustments)
     420              : {
     421        47983 :   auto it = autoderef_mappings.find (id);
     422        47983 :   if (it == autoderef_mappings.end ())
     423              :     return false;
     424              : 
     425        34757 :   *adjustments = &it->second;
     426        34757 :   return true;
     427              : }
     428              : 
     429              : void
     430         5274 : TypeCheckContext::insert_cast_autoderef_mappings (
     431              :   HirId id, std::vector<Adjustment> &&adjustments)
     432              : {
     433         5274 :   cast_autoderef_mappings.emplace (id, std::move (adjustments));
     434         5274 : }
     435              : 
     436              : bool
     437         4954 : TypeCheckContext::lookup_cast_autoderef_mappings (
     438              :   HirId id, std::vector<Adjustment> **adjustments)
     439              : {
     440         4954 :   auto it = cast_autoderef_mappings.find (id);
     441         4954 :   if (it == cast_autoderef_mappings.end ())
     442              :     return false;
     443              : 
     444         4954 :   *adjustments = &it->second;
     445         4954 :   return true;
     446              : }
     447              : 
     448              : void
     449         4274 : TypeCheckContext::insert_variant_definition (HirId id, HirId variant)
     450              : {
     451         4274 :   auto it = variants.find (id);
     452         4274 :   rust_assert (it == variants.end ());
     453              : 
     454         4274 :   variants[id] = variant;
     455         4274 : }
     456              : 
     457              : bool
     458         8363 : TypeCheckContext::lookup_variant_definition (HirId id, HirId *variant)
     459              : {
     460         8363 :   auto it = variants.find (id);
     461         8363 :   if (it == variants.end ())
     462              :     return false;
     463              : 
     464         8357 :   *variant = it->second;
     465         8357 :   return true;
     466              : }
     467              : 
     468              : void
     469         1330 : TypeCheckContext::insert_operator_overload (HirId id, TyTy::FnType *call_site)
     470              : {
     471         1330 :   auto it = operator_overloads.find (id);
     472         1330 :   rust_assert (it == operator_overloads.end ());
     473              : 
     474         1330 :   operator_overloads[id] = call_site;
     475         1330 : }
     476              : 
     477              : bool
     478        23435 : TypeCheckContext::lookup_operator_overload (HirId id, TyTy::FnType **call)
     479              : {
     480        23435 :   auto it = operator_overloads.find (id);
     481        23435 :   if (it == operator_overloads.end ())
     482              :     return false;
     483              : 
     484         2352 :   *call = it->second;
     485         2352 :   return true;
     486              : }
     487              : 
     488              : void
     489            8 : TypeCheckContext::insert_deferred_operator_overload (
     490              :   DeferredOpOverload deferred)
     491              : {
     492            8 :   HirId expr_id = deferred.expr_id;
     493            8 :   deferred_operator_overloads.emplace (std::make_pair (expr_id, deferred));
     494            8 : }
     495              : 
     496              : bool
     497            0 : TypeCheckContext::lookup_deferred_operator_overload (
     498              :   HirId id, DeferredOpOverload *deferred)
     499              : {
     500            0 :   auto it = deferred_operator_overloads.find (id);
     501            0 :   if (it == deferred_operator_overloads.end ())
     502              :     return false;
     503              : 
     504            0 :   *deferred = it->second;
     505            0 :   return true;
     506              : }
     507              : 
     508              : void
     509         4346 : TypeCheckContext::iterate_deferred_operator_overloads (
     510              :   std::function<bool (HirId, DeferredOpOverload &)> cb)
     511              : {
     512         4354 :   for (auto it = deferred_operator_overloads.begin ();
     513         4354 :        it != deferred_operator_overloads.end (); it++)
     514              :     {
     515            8 :       if (!cb (it->first, it->second))
     516         4346 :         return;
     517              :     }
     518              : }
     519              : 
     520              : void
     521         5740 : TypeCheckContext::insert_unconstrained_check_marker (HirId id, bool status)
     522              : {
     523         5740 :   unconstrained[id] = status;
     524         5740 : }
     525              : 
     526              : bool
     527        43721 : TypeCheckContext::have_checked_for_unconstrained (HirId id, bool *result)
     528              : {
     529        43721 :   auto it = unconstrained.find (id);
     530        43721 :   bool found = it != unconstrained.end ();
     531        43721 :   if (!found)
     532              :     return false;
     533              : 
     534        37981 :   *result = it->second;
     535        37981 :   return true;
     536              : }
     537              : 
     538              : void
     539         6921 : TypeCheckContext::insert_resolved_predicate (HirId id,
     540              :                                              TyTy::TypeBoundPredicate predicate)
     541              : {
     542              :   // auto it = predicates.find (id);
     543              :   // rust_assert (it == predicates.end ());
     544              : 
     545         6921 :   predicates.insert ({id, predicate});
     546         6921 : }
     547              : 
     548              : bool
     549        43199 : TypeCheckContext::lookup_predicate (HirId id, TyTy::TypeBoundPredicate *result)
     550              : {
     551        43199 :   auto it = predicates.find (id);
     552        43199 :   bool found = it != predicates.end ();
     553        43199 :   if (!found)
     554              :     return false;
     555              : 
     556        36269 :   *result = it->second;
     557        36269 :   return true;
     558              : }
     559              : 
     560              : void
     561        10960 : TypeCheckContext::insert_query (HirId id)
     562              : {
     563        10960 :   querys_in_progress.insert (id);
     564        10960 : }
     565              : 
     566              : void
     567        10960 : TypeCheckContext::query_completed (HirId id)
     568              : {
     569        10960 :   querys_in_progress.erase (id);
     570        10960 : }
     571              : 
     572              : bool
     573        16538 : TypeCheckContext::query_in_progress (HirId id) const
     574              : {
     575        16538 :   return querys_in_progress.find (id) != querys_in_progress.end ();
     576              : }
     577              : 
     578              : void
     579         3934 : TypeCheckContext::insert_trait_query (DefId id)
     580              : {
     581         3934 :   trait_queries_in_progress.insert (id);
     582         3934 : }
     583              : 
     584              : void
     585         3934 : TypeCheckContext::trait_query_completed (DefId id)
     586              : {
     587         3934 :   trait_queries_in_progress.erase (id);
     588         3934 : }
     589              : 
     590              : bool
     591         3938 : TypeCheckContext::trait_query_in_progress (DefId id) const
     592              : {
     593         3938 :   return trait_queries_in_progress.find (id)
     594         3938 :          != trait_queries_in_progress.end ();
     595              : }
     596              : 
     597              : Lifetime
     598          967 : TypeCheckContext::intern_lifetime (const HIR::Lifetime &lifetime)
     599              : {
     600          967 :   if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
     601              :     {
     602          966 :       auto maybe_interned = lookup_lifetime (lifetime);
     603          966 :       if (maybe_interned)
     604          870 :         return *maybe_interned;
     605              : 
     606           96 :       auto interned = next_lifetime_index.next ();
     607           96 :       lifetime_name_interner[lifetime.get_name ()] = interned;
     608           96 :       return interned;
     609              :     }
     610            1 :   if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
     611              :     {
     612            1 :       return next_lifetime_index.next ();
     613              :     }
     614            0 :   if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
     615              :     {
     616            0 :       return Lifetime::static_lifetime ();
     617              :     }
     618            0 :   rust_unreachable ();
     619              : }
     620              : 
     621              : tl::optional<Lifetime>
     622        30692 : TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const
     623              : {
     624        30692 :   if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
     625              :     {
     626         1243 :       if (lifetime.get_name () == "static")
     627              :         {
     628            1 :           rich_location r (line_table, lifetime.get_locus ());
     629            1 :           r.add_fixit_insert_after (lifetime.get_locus (),
     630              :                                     "static is a reserved lifetime name");
     631            1 :           rust_error_at (r, ErrorCode::E0262,
     632              :                          "invalid lifetime parameter name: %qs",
     633            1 :                          lifetime.get_name ().c_str ());
     634            1 :           return tl::nullopt;
     635            1 :         }
     636         1242 :       const auto name = lifetime.get_name ();
     637         1242 :       auto it = lifetime_name_interner.find (name);
     638         1242 :       if (it == lifetime_name_interner.end ())
     639          100 :         return tl::nullopt;
     640         1142 :       return it->second;
     641         1242 :     }
     642        29449 :   if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
     643              :     {
     644        29360 :       return Lifetime::anonymous_lifetime ();
     645              :     }
     646           89 :   if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
     647              :     {
     648           89 :       return Lifetime::static_lifetime ();
     649              :     }
     650            0 :   rust_unreachable ();
     651              : }
     652              : 
     653              : WARN_UNUSED_RESULT tl::optional<TyTy::Region>
     654        29726 : TypeCheckContext::lookup_and_resolve_lifetime (
     655              :   const HIR::Lifetime &lifetime) const
     656              : {
     657        29726 :   auto maybe_interned = lookup_lifetime (lifetime);
     658        29726 :   if (!maybe_interned)
     659            5 :     return tl::nullopt;
     660              : 
     661        29721 :   return get_lifetime_resolver ().resolve (maybe_interned.value ());
     662              : }
     663              : void
     664           16 : TypeCheckContext::intern_and_insert_lifetime (const HIR::Lifetime &lifetime)
     665              : {
     666           16 :   get_lifetime_resolver ().insert_mapping (intern_lifetime (lifetime));
     667           16 : }
     668              : 
     669              : WARN_UNUSED_RESULT std::vector<TyTy::Region>
     670         9379 : TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
     671              : {
     672         9379 :   std::vector<TyTy::Region> regions;
     673         9408 :   for (const auto &lifetime : args.get_lifetime_args ())
     674              :     {
     675           30 :       auto resolved = lookup_and_resolve_lifetime (lifetime);
     676           30 :       if (!resolved)
     677              :         {
     678            1 :           rust_error_at (lifetime.get_locus (), "unresolved lifetime");
     679            1 :           return {};
     680              :         }
     681           29 :       regions.push_back (*resolved);
     682              :     }
     683         9378 :   return regions;
     684         9379 : }
     685              : 
     686              : bool
     687            8 : TypeCheckContext::compute_ambigious_op_overload (HirId id,
     688              :                                                  DeferredOpOverload &op)
     689              : {
     690            8 :   rust_debug ("attempting resolution of op overload: %s",
     691              :               op.predicate.as_string ().c_str ());
     692              : 
     693            8 :   TyTy::BaseType *lhs = nullptr;
     694            8 :   bool ok = lookup_type (op.op.get_lvalue_mappings ().get_hirid (), &lhs);
     695            8 :   rust_assert (ok);
     696              : 
     697            8 :   TyTy::BaseType *rhs = nullptr;
     698            8 :   if (op.op.has_rvalue_mappings ())
     699              :     {
     700            8 :       bool ok = lookup_type (op.op.get_rvalue_mappings ().get_hirid (), &rhs);
     701            8 :       rust_assert (ok);
     702              :     }
     703              : 
     704            8 :   TypeCheckExpr::ResolveOpOverload (op.lang_item_type, op.op, lhs, rhs,
     705            8 :                                     op.specified_segment);
     706              : 
     707            8 :   return true;
     708              : }
     709              : 
     710              : void
     711         4346 : TypeCheckContext::compute_inference_variables (bool emit_error)
     712              : {
     713         4346 :   iterate_deferred_operator_overloads (
     714         4346 :     [&] (HirId id, DeferredOpOverload &op) mutable -> bool {
     715            8 :       return compute_ambigious_op_overload (id, op);
     716              :     });
     717              : 
     718         4346 :   iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
     719       500352 :     return compute_infer_var (id, ty, emit_error);
     720              :   });
     721         4346 : }
     722              : 
     723              : bool
     724       500352 : TypeCheckContext::compute_infer_var (HirId id, TyTy::BaseType *ty,
     725              :                                      bool emit_error)
     726              : {
     727       500352 :   auto &mappings = Analysis::Mappings::get ();
     728              : 
     729              :   // nothing to do
     730       500352 :   if (ty->get_kind () != TyTy::TypeKind::INFER)
     731              :     return true;
     732              : 
     733         1683 :   TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
     734         1683 :   TyTy::BaseType *default_type;
     735              : 
     736         1683 :   rust_debug_loc (mappings.lookup_location (id),
     737              :                   "trying to default infer-var: %s",
     738         1683 :                   infer_var->as_string ().c_str ());
     739         1683 :   bool ok = infer_var->default_type (&default_type);
     740         1683 :   if (!ok)
     741              :     {
     742           11 :       if (emit_error)
     743           11 :         rust_error_at (mappings.lookup_location (id), ErrorCode::E0282,
     744              :                        "type annotations needed");
     745           11 :       return true;
     746              :     }
     747              : 
     748         1672 :   auto result
     749         1672 :     = unify_site (id, TyTy::TyWithLocation (ty),
     750         1672 :                   TyTy::TyWithLocation (default_type), UNDEF_LOCATION);
     751         1672 :   rust_assert (result);
     752         1672 :   rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
     753         1672 :   result->set_ref (id);
     754         1672 :   insert_implicit_type (id, result);
     755              : 
     756         1672 :   return true;
     757              : }
     758              : 
     759              : TyTy::VarianceAnalysis::CrateCtx &
     760         8286 : TypeCheckContext::get_variance_analysis_ctx ()
     761              : {
     762         8286 :   return variance_analysis_ctx;
     763              : }
     764              : 
     765              : // TypeCheckContextItem
     766              : 
     767         9394 : TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
     768              : 
     769         6928 : TypeCheckContextItem::Item::Item (HIR::ImplBlock *impl_block,
     770              :                                   HIR::Function *item)
     771         6928 :   : impl_item ({impl_block, item})
     772         6928 : {}
     773              : 
     774          858 : TypeCheckContextItem::Item::Item (HIR::TraitItemFunc *trait_item)
     775          858 :   : trait_item (trait_item)
     776          858 : {}
     777              : 
     778         6577 : TypeCheckContextItem::TypeCheckContextItem (HIR::Function *item)
     779         6577 :   : type (ItemType::ITEM), item (item)
     780         6577 : {}
     781              : 
     782         6928 : TypeCheckContextItem::TypeCheckContextItem (HIR::ImplBlock &impl_block,
     783         6928 :                                             HIR::Function *item)
     784         6928 :   : type (ItemType::IMPL_ITEM), item (&impl_block, item)
     785         6928 : {}
     786              : 
     787          858 : TypeCheckContextItem::TypeCheckContextItem (HIR::TraitItemFunc *trait_item)
     788          858 :   : type (ItemType::TRAIT_ITEM), item (trait_item)
     789          858 : {}
     790              : 
     791        18836 : TypeCheckContextItem::TypeCheckContextItem (const TypeCheckContextItem &other)
     792        18836 :   : type (other.type), item (other.item)
     793              : {
     794        18836 :   switch (other.type)
     795              :     {
     796              :     case ITEM:
     797              :       item.item = other.item.item;
     798              :       break;
     799              : 
     800         9877 :     case IMPL_ITEM:
     801         9877 :       item.impl_item = other.item.impl_item;
     802         9877 :       break;
     803              : 
     804              :     case TRAIT_ITEM:
     805              :       item.trait_item = other.item.trait_item;
     806              :       break;
     807              : 
     808            0 :     case ERROR:
     809            0 :       item.item = nullptr;
     810            0 :       break;
     811              :     }
     812        18836 : }
     813              : 
     814         2817 : TypeCheckContextItem::TypeCheckContextItem ()
     815         2817 :   : type (ItemType::ERROR), item (static_cast<HIR::Function *> (nullptr))
     816         2817 : {}
     817              : 
     818              : TypeCheckContextItem &
     819         2809 : TypeCheckContextItem::operator= (const TypeCheckContextItem &other)
     820              : {
     821         2809 :   type = other.type;
     822         2809 :   switch (other.type)
     823              :     {
     824          630 :     case ITEM:
     825          630 :       item.item = other.item.item;
     826          630 :       break;
     827              : 
     828         2065 :     case IMPL_ITEM:
     829         2065 :       item.impl_item = other.item.impl_item;
     830         2065 :       break;
     831              : 
     832          114 :     case TRAIT_ITEM:
     833          114 :       item.trait_item = other.item.trait_item;
     834          114 :       break;
     835              : 
     836            0 :     case ERROR:
     837            0 :       item.item = nullptr;
     838            0 :       break;
     839              :     }
     840              : 
     841         2809 :   return *this;
     842              : }
     843              : 
     844              : TypeCheckContextItem
     845         2817 : TypeCheckContextItem::get_error ()
     846              : {
     847         2817 :   return TypeCheckContextItem ();
     848              : }
     849              : 
     850              : bool
     851            0 : TypeCheckContextItem::is_error () const
     852              : {
     853            0 :   return type == ERROR;
     854              : }
     855              : 
     856              : HIR::Function *
     857           63 : TypeCheckContextItem::get_item ()
     858              : {
     859           63 :   rust_assert (get_type () == ItemType::ITEM);
     860           63 :   return item.item;
     861              : }
     862              : 
     863              : std::pair<HIR::ImplBlock *, HIR::Function *> &
     864          771 : TypeCheckContextItem::get_impl_item ()
     865              : {
     866          771 :   rust_assert (get_type () == ItemType::IMPL_ITEM);
     867          771 :   return item.impl_item;
     868              : }
     869              : 
     870              : HIR::TraitItemFunc *
     871            1 : TypeCheckContextItem::get_trait_item ()
     872              : {
     873            1 :   rust_assert (get_type () == ItemType::TRAIT_ITEM);
     874            1 :   return item.trait_item;
     875              : }
     876              : 
     877              : TypeCheckContextItem::ItemType
     878         5245 : TypeCheckContextItem::get_type () const
     879              : {
     880         5245 :   return type;
     881              : }
     882              : 
     883              : TyTy::FnType *
     884           64 : TypeCheckContextItem::get_context_type ()
     885              : {
     886           64 :   auto &context = *TypeCheckContext::get ();
     887              : 
     888           64 :   HirId reference = UNKNOWN_HIRID;
     889           64 :   switch (get_type ())
     890              :     {
     891           63 :     case ITEM:
     892           63 :       reference = get_item ()->get_mappings ().get_hirid ();
     893           63 :       break;
     894              : 
     895            0 :     case IMPL_ITEM:
     896            0 :       reference = get_impl_item ().second->get_mappings ().get_hirid ();
     897            0 :       break;
     898              : 
     899            1 :     case TRAIT_ITEM:
     900            1 :       reference = get_trait_item ()->get_mappings ().get_hirid ();
     901            1 :       break;
     902              : 
     903            0 :     case ERROR:
     904            0 :       rust_unreachable ();
     905              :       return nullptr;
     906              :     }
     907              : 
     908           64 :   rust_assert (reference != UNKNOWN_HIRID);
     909              : 
     910           64 :   TyTy::BaseType *lookup = nullptr;
     911           64 :   bool ok = context.lookup_type (reference, &lookup);
     912           64 :   rust_assert (ok);
     913           64 :   rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
     914           64 :   return static_cast<TyTy::FnType *> (lookup);
     915              : }
     916              : 
     917              : DefId
     918         2853 : TypeCheckContextItem::get_defid () const
     919              : {
     920         2853 :   switch (get_type ())
     921              :     {
     922          744 :     case ITEM:
     923          744 :       return item.item->get_mappings ().get_defid ();
     924              : 
     925         1987 :     case IMPL_ITEM:
     926         1987 :       return item.impl_item.second->get_mappings ().get_defid ();
     927              : 
     928          114 :     case TRAIT_ITEM:
     929          114 :       return item.trait_item->get_mappings ().get_defid ();
     930              : 
     931            8 :     case ERROR:
     932            8 :       return UNKNOWN_DEFID;
     933              :     }
     934              : 
     935            0 :   return UNKNOWN_DEFID;
     936              : }
     937              : 
     938              : // TypeCheckBlockContextItem
     939              : 
     940         8182 : TypeCheckBlockContextItem::Item::Item (HIR::ImplBlock *b) : block (b) {}
     941              : 
     942         3915 : TypeCheckBlockContextItem::Item::Item (HIR::Trait *t) : trait (t) {}
     943              : 
     944         8182 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::ImplBlock *block)
     945         8182 :   : type (TypeCheckBlockContextItem::ItemType::IMPL_BLOCK), item (block)
     946         8182 : {}
     947              : 
     948         3915 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::Trait *trait)
     949         3915 :   : type (TypeCheckBlockContextItem::ItemType::TRAIT), item (trait)
     950         3915 : {}
     951              : 
     952              : bool
     953            0 : TypeCheckBlockContextItem::is_impl_block () const
     954              : {
     955            0 :   return type == IMPL_BLOCK;
     956              : }
     957              : 
     958              : bool
     959          891 : TypeCheckBlockContextItem::is_trait_block () const
     960              : {
     961          891 :   return type == TRAIT;
     962              : }
     963              : 
     964              : HIR::ImplBlock &
     965          158 : TypeCheckBlockContextItem::get_impl_block ()
     966              : {
     967          158 :   return *(item.block);
     968              : }
     969              : 
     970              : HIR::Trait &
     971          733 : TypeCheckBlockContextItem::get_trait ()
     972              : {
     973          733 :   return *(item.trait);
     974              : }
     975              : 
     976              : } // namespace Resolver
     977              : } // 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.