LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-typecheck-context.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.4 % 430 380
Test Date: 2026-02-28 14:20:25 Functions: 91.1 % 90 82
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     20870337 : TypeCheckContext::get ()
      28              : {
      29     20870337 :   static TypeCheckContext *instance;
      30     20870337 :   if (instance == nullptr)
      31         4510 :     instance = new TypeCheckContext ();
      32              : 
      33     20870337 :   return instance;
      34              : }
      35              : 
      36         4510 : 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        31605 : TypeCheckContext::lookup_builtin (std::string name, TyTy::BaseType **type)
      57              : {
      58       371606 :   for (auto &builtin : builtins)
      59              :     {
      60       371606 :       if (name.compare (builtin->as_string ()) == 0)
      61              :         {
      62        31605 :           *type = builtin.get ();
      63        31605 :           return true;
      64              :         }
      65              :     }
      66              :   return false;
      67              : }
      68              : 
      69              : void
      70        85614 : TypeCheckContext::insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type)
      71              : {
      72        85614 :   node_id_refs[ref] = id;
      73        85614 :   resolved[id] = type;
      74        85614 :   builtins.push_back (std::unique_ptr<TyTy::BaseType> (type));
      75        85614 : }
      76              : 
      77              : const std::vector<std::unique_ptr<TyTy::BaseType>> &
      78         4301 : TypeCheckContext::get_builtins () const
      79              : {
      80         4301 :   return builtins;
      81              : }
      82              : 
      83              : void
      84       459225 : TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings,
      85              :                                TyTy::BaseType *type)
      86              : {
      87       459225 :   rust_assert (type != nullptr);
      88       459225 :   NodeId ref = mappings.get_nodeid ();
      89       459225 :   HirId id = mappings.get_hirid ();
      90       459225 :   node_id_refs[ref] = id;
      91       459225 :   resolved[id] = type;
      92       459225 : }
      93              : 
      94              : void
      95       223356 : TypeCheckContext::insert_implicit_type (HirId id, TyTy::BaseType *type)
      96              : {
      97       223356 :   rust_assert (type != nullptr);
      98       223356 :   resolved[id] = type;
      99       223356 : }
     100              : 
     101              : bool
     102     14484975 : TypeCheckContext::lookup_type (HirId id, TyTy::BaseType **type) const
     103              : {
     104     14484975 :   auto it = resolved.find (id);
     105     14484975 :   if (it == resolved.end ())
     106              :     return false;
     107              : 
     108     14304642 :   *type = it->second;
     109     14304642 :   return true;
     110              : }
     111              : 
     112              : void
     113        84982 : TypeCheckContext::clear_type (TyTy::BaseType *ty)
     114              : {
     115        84982 :   auto it = resolved.find (ty->get_ref ());
     116        84982 :   if (it == resolved.end ())
     117        84982 :     return;
     118              : 
     119        84982 :   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         3410 : TypeCheckContext::have_function_context () const
     142              : {
     143         3410 :   return !return_type_stack.empty ();
     144              : }
     145              : 
     146              : TyTy::BaseType *
     147          527 : TypeCheckContext::peek_return_type ()
     148              : {
     149          527 :   rust_assert (!return_type_stack.empty ());
     150          527 :   return return_type_stack.back ().second;
     151              : }
     152              : 
     153              : void
     154        14016 : TypeCheckContext::push_return_type (TypeCheckContextItem item,
     155              :                                     TyTy::BaseType *return_type)
     156              : {
     157        14016 :   return_type_stack.emplace_back (std::move (item), return_type);
     158        14016 : }
     159              : 
     160              : void
     161        14016 : TypeCheckContext::pop_return_type ()
     162              : {
     163        14016 :   rust_assert (!return_type_stack.empty ());
     164        14016 :   return_type_stack.pop_back ();
     165        14016 : }
     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              : StackedContexts<TypeCheckBlockContextItem> &
     175        25208 : TypeCheckContext::block_context ()
     176              : {
     177        25208 :   return block_stack;
     178              : }
     179              : 
     180              : void
     181         4129 : TypeCheckContext::iterate (std::function<bool (HirId, TyTy::BaseType *)> cb)
     182              : {
     183       456187 :   for (auto it = resolved.begin (); it != resolved.end (); it++)
     184              :     {
     185       452058 :       if (!cb (it->first, it->second))
     186         4129 :         return;
     187              :     }
     188              : }
     189              : 
     190              : bool
     191          103 : TypeCheckContext::have_loop_context () const
     192              : {
     193          103 :   return !loop_type_stack.empty ();
     194              : }
     195              : 
     196              : void
     197          124 : TypeCheckContext::push_new_loop_context (HirId id, location_t locus)
     198              : {
     199          124 :   TyTy::BaseType *infer_var
     200              :     = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
     201          124 :                            TyTy::InferType::TypeHint::Default (), locus);
     202          124 :   loop_type_stack.push_back (infer_var);
     203          124 : }
     204              : 
     205              : void
     206           77 : TypeCheckContext::push_new_while_loop_context (HirId id)
     207              : {
     208           77 :   TyTy::BaseType *infer_var = new TyTy::ErrorType (id);
     209           77 :   loop_type_stack.push_back (infer_var);
     210           77 : }
     211              : 
     212              : TyTy::BaseType *
     213          220 : TypeCheckContext::peek_loop_context ()
     214              : {
     215          220 :   return loop_type_stack.back ();
     216              : }
     217              : 
     218              : TyTy::BaseType *
     219          201 : TypeCheckContext::pop_loop_context ()
     220              : {
     221          201 :   auto back = peek_loop_context ();
     222          201 :   loop_type_stack.pop_back ();
     223          201 :   return back;
     224              : }
     225              : 
     226              : void
     227           15 : TypeCheckContext::swap_head_loop_context (TyTy::BaseType *val)
     228              : {
     229           15 :   loop_type_stack.pop_back ();
     230           15 :   loop_type_stack.push_back (val);
     231           15 : }
     232              : 
     233              : void
     234         3680 : TypeCheckContext::insert_trait_reference (DefId id, TraitReference &&ref)
     235              : {
     236         3680 :   rust_assert (trait_context.find (id) == trait_context.end ());
     237         3680 :   trait_context.emplace (id, std::move (ref));
     238         3680 : }
     239              : 
     240              : bool
     241      1048281 : TypeCheckContext::lookup_trait_reference (DefId id, TraitReference **ref)
     242              : {
     243      1048281 :   auto it = trait_context.find (id);
     244      1048281 :   if (it == trait_context.end ())
     245              :     return false;
     246              : 
     247      1020957 :   *ref = &it->second;
     248      1020957 :   return true;
     249              : }
     250              : 
     251              : bool
     252         4651 : TypeCheckContext::insert_associated_trait_impl (
     253              :   HirId id, AssociatedImplTrait &&associated)
     254              : {
     255         4651 :   auto it = associated_impl_traits.find (id);
     256         4651 :   if (it != associated_impl_traits.end ())
     257              :     {
     258              :       return false;
     259              :     }
     260         4650 :   associated_impl_traits.emplace (id, std::move (associated));
     261         4650 :   return true;
     262              : }
     263              : 
     264              : bool
     265        51191 : TypeCheckContext::lookup_associated_trait_impl (
     266              :   HirId id, AssociatedImplTrait **associated)
     267              : {
     268        51191 :   auto it = associated_impl_traits.find (id);
     269        51191 :   if (it == associated_impl_traits.end ())
     270              :     return false;
     271              : 
     272        26235 :   *associated = &it->second;
     273        26235 :   return true;
     274              : }
     275              : 
     276              : void
     277         3061 : TypeCheckContext::insert_associated_type_mapping (HirId id, HirId mapping)
     278              : {
     279         3061 :   associated_type_mappings[id] = mapping;
     280         3061 : }
     281              : 
     282              : void
     283         1191 : TypeCheckContext::clear_associated_type_mapping (HirId id)
     284              : {
     285         1191 :   auto it = associated_type_mappings.find (id);
     286         1191 :   if (it != associated_type_mappings.end ())
     287         1189 :     associated_type_mappings.erase (it);
     288         1191 : }
     289              : 
     290              : // lookup any associated type mappings, the out parameter of mapping is
     291              : // allowed to be nullptr which allows this interface to do a simple does exist
     292              : // check
     293              : bool
     294       132697 : TypeCheckContext::lookup_associated_type_mapping (HirId id, HirId *mapping)
     295              : {
     296       132697 :   auto it = associated_type_mappings.find (id);
     297       132697 :   if (it == associated_type_mappings.end ())
     298              :     return false;
     299              : 
     300        49188 :   if (mapping != nullptr)
     301        49188 :     *mapping = it->second;
     302              : 
     303              :   return true;
     304              : }
     305              : 
     306              : void
     307         4651 : TypeCheckContext::insert_associated_impl_mapping (HirId trait_id,
     308              :                                                   TyTy::BaseType *impl_type,
     309              :                                                   HirId impl_id)
     310              : {
     311         4651 :   auto it = associated_traits_to_impls.find (trait_id);
     312         4651 :   if (it == associated_traits_to_impls.end ())
     313              :     {
     314         1776 :       associated_traits_to_impls[trait_id] = {};
     315              :     }
     316              : 
     317         4651 :   associated_traits_to_impls[trait_id].emplace_back (impl_type, impl_id);
     318         4651 : }
     319              : 
     320              : bool
     321            0 : TypeCheckContext::lookup_associated_impl_mapping_for_self (HirId trait_id,
     322              :                                                            TyTy::BaseType *self,
     323              :                                                            HirId *mapping)
     324              : {
     325            0 :   auto it = associated_traits_to_impls.find (trait_id);
     326            0 :   if (it == associated_traits_to_impls.end ())
     327              :     return false;
     328              : 
     329            0 :   for (auto &item : it->second)
     330              :     {
     331            0 :       if (types_compatable (TyTy::TyWithLocation (item.first),
     332            0 :                             TyTy::TyWithLocation (self), UNKNOWN_LOCATION,
     333              :                             false))
     334              :         {
     335            0 :           *mapping = item.second;
     336            0 :           return true;
     337              :         }
     338              :     }
     339              :   return false;
     340              : }
     341              : 
     342              : void
     343        42735 : TypeCheckContext::insert_autoderef_mappings (
     344              :   HirId id, std::vector<Adjustment> &&adjustments)
     345              : {
     346        42735 :   autoderef_mappings.emplace (id, std::move (adjustments));
     347        42735 : }
     348              : 
     349              : bool
     350        46481 : TypeCheckContext::lookup_autoderef_mappings (
     351              :   HirId id, std::vector<Adjustment> **adjustments)
     352              : {
     353        46481 :   auto it = autoderef_mappings.find (id);
     354        46481 :   if (it == autoderef_mappings.end ())
     355              :     return false;
     356              : 
     357        33481 :   *adjustments = &it->second;
     358        33481 :   return true;
     359              : }
     360              : 
     361              : void
     362         5161 : TypeCheckContext::insert_cast_autoderef_mappings (
     363              :   HirId id, std::vector<Adjustment> &&adjustments)
     364              : {
     365         5161 :   cast_autoderef_mappings.emplace (id, std::move (adjustments));
     366         5161 : }
     367              : 
     368              : bool
     369         4853 : TypeCheckContext::lookup_cast_autoderef_mappings (
     370              :   HirId id, std::vector<Adjustment> **adjustments)
     371              : {
     372         4853 :   auto it = cast_autoderef_mappings.find (id);
     373         4853 :   if (it == cast_autoderef_mappings.end ())
     374              :     return false;
     375              : 
     376         4853 :   *adjustments = &it->second;
     377         4853 :   return true;
     378              : }
     379              : 
     380              : void
     381         4240 : TypeCheckContext::insert_variant_definition (HirId id, HirId variant)
     382              : {
     383         4240 :   auto it = variants.find (id);
     384         4240 :   rust_assert (it == variants.end ());
     385              : 
     386         4240 :   variants[id] = variant;
     387         4240 : }
     388              : 
     389              : bool
     390         8306 : TypeCheckContext::lookup_variant_definition (HirId id, HirId *variant)
     391              : {
     392         8306 :   auto it = variants.find (id);
     393         8306 :   if (it == variants.end ())
     394              :     return false;
     395              : 
     396         8300 :   *variant = it->second;
     397         8300 :   return true;
     398              : }
     399              : 
     400              : void
     401         1330 : TypeCheckContext::insert_operator_overload (HirId id, TyTy::FnType *call_site)
     402              : {
     403         1330 :   auto it = operator_overloads.find (id);
     404         1330 :   rust_assert (it == operator_overloads.end ());
     405              : 
     406         1330 :   operator_overloads[id] = call_site;
     407         1330 : }
     408              : 
     409              : bool
     410        20946 : TypeCheckContext::lookup_operator_overload (HirId id, TyTy::FnType **call)
     411              : {
     412        20946 :   auto it = operator_overloads.find (id);
     413        20946 :   if (it == operator_overloads.end ())
     414              :     return false;
     415              : 
     416         2352 :   *call = it->second;
     417         2352 :   return true;
     418              : }
     419              : 
     420              : void
     421            8 : TypeCheckContext::insert_deferred_operator_overload (
     422              :   DeferredOpOverload deferred)
     423              : {
     424            8 :   HirId expr_id = deferred.expr_id;
     425            8 :   deferred_operator_overloads.emplace (std::make_pair (expr_id, deferred));
     426            8 : }
     427              : 
     428              : bool
     429            0 : TypeCheckContext::lookup_deferred_operator_overload (
     430              :   HirId id, DeferredOpOverload *deferred)
     431              : {
     432            0 :   auto it = deferred_operator_overloads.find (id);
     433            0 :   if (it == deferred_operator_overloads.end ())
     434              :     return false;
     435              : 
     436            0 :   *deferred = it->second;
     437            0 :   return true;
     438              : }
     439              : 
     440              : void
     441         4129 : TypeCheckContext::iterate_deferred_operator_overloads (
     442              :   std::function<bool (HirId, DeferredOpOverload &)> cb)
     443              : {
     444         4137 :   for (auto it = deferred_operator_overloads.begin ();
     445         4137 :        it != deferred_operator_overloads.end (); it++)
     446              :     {
     447            8 :       if (!cb (it->first, it->second))
     448         4129 :         return;
     449              :     }
     450              : }
     451              : 
     452              : void
     453         5640 : TypeCheckContext::insert_unconstrained_check_marker (HirId id, bool status)
     454              : {
     455         5640 :   unconstrained[id] = status;
     456         5640 : }
     457              : 
     458              : bool
     459        41263 : TypeCheckContext::have_checked_for_unconstrained (HirId id, bool *result)
     460              : {
     461        41263 :   auto it = unconstrained.find (id);
     462        41263 :   bool found = it != unconstrained.end ();
     463        41263 :   if (!found)
     464              :     return false;
     465              : 
     466        35623 :   *result = it->second;
     467        35623 :   return true;
     468              : }
     469              : 
     470              : void
     471         6748 : TypeCheckContext::insert_resolved_predicate (HirId id,
     472              :                                              TyTy::TypeBoundPredicate predicate)
     473              : {
     474              :   // auto it = predicates.find (id);
     475              :   // rust_assert (it == predicates.end ());
     476              : 
     477         6748 :   predicates.insert ({id, predicate});
     478         6748 : }
     479              : 
     480              : bool
     481        38136 : TypeCheckContext::lookup_predicate (HirId id, TyTy::TypeBoundPredicate *result)
     482              : {
     483        38136 :   auto it = predicates.find (id);
     484        38136 :   bool found = it != predicates.end ();
     485        38136 :   if (!found)
     486              :     return false;
     487              : 
     488        31379 :   *result = it->second;
     489        31379 :   return true;
     490              : }
     491              : 
     492              : void
     493        11177 : TypeCheckContext::insert_query (HirId id)
     494              : {
     495        11177 :   querys_in_progress.insert (id);
     496        11177 : }
     497              : 
     498              : void
     499        11177 : TypeCheckContext::query_completed (HirId id)
     500              : {
     501        11177 :   querys_in_progress.erase (id);
     502        11177 : }
     503              : 
     504              : bool
     505        16714 : TypeCheckContext::query_in_progress (HirId id) const
     506              : {
     507        16714 :   return querys_in_progress.find (id) != querys_in_progress.end ();
     508              : }
     509              : 
     510              : void
     511         3688 : TypeCheckContext::insert_trait_query (DefId id)
     512              : {
     513         3688 :   trait_queries_in_progress.insert (id);
     514         3688 : }
     515              : 
     516              : void
     517         3688 : TypeCheckContext::trait_query_completed (DefId id)
     518              : {
     519         3688 :   trait_queries_in_progress.erase (id);
     520         3688 : }
     521              : 
     522              : bool
     523         3692 : TypeCheckContext::trait_query_in_progress (DefId id) const
     524              : {
     525         3692 :   return trait_queries_in_progress.find (id)
     526         3692 :          != trait_queries_in_progress.end ();
     527              : }
     528              : 
     529              : Lifetime
     530          902 : TypeCheckContext::intern_lifetime (const HIR::Lifetime &lifetime)
     531              : {
     532          902 :   if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
     533              :     {
     534          901 :       auto maybe_interned = lookup_lifetime (lifetime);
     535          901 :       if (maybe_interned)
     536          816 :         return *maybe_interned;
     537              : 
     538           85 :       auto interned = next_lifetime_index.next ();
     539           85 :       lifetime_name_interner[lifetime.get_name ()] = interned;
     540           85 :       return interned;
     541              :     }
     542            1 :   if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
     543              :     {
     544            1 :       return next_lifetime_index.next ();
     545              :     }
     546            0 :   if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
     547              :     {
     548            0 :       return Lifetime::static_lifetime ();
     549              :     }
     550            0 :   rust_unreachable ();
     551              : }
     552              : 
     553              : tl::optional<Lifetime>
     554        30320 : TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const
     555              : {
     556        30320 :   if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
     557              :     {
     558         1176 :       if (lifetime.get_name () == "static")
     559              :         {
     560            1 :           rich_location r (line_table, lifetime.get_locus ());
     561            1 :           r.add_fixit_insert_after (lifetime.get_locus (),
     562              :                                     "static is a reserved lifetime name");
     563            1 :           rust_error_at (r, ErrorCode::E0262,
     564              :                          "invalid lifetime parameter name: %qs",
     565            1 :                          lifetime.get_name ().c_str ());
     566            1 :           return tl::nullopt;
     567            1 :         }
     568         1175 :       const auto name = lifetime.get_name ();
     569         1175 :       auto it = lifetime_name_interner.find (name);
     570         1175 :       if (it == lifetime_name_interner.end ())
     571           90 :         return tl::nullopt;
     572         1085 :       return it->second;
     573         1175 :     }
     574        29144 :   if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
     575              :     {
     576        29055 :       return Lifetime::anonymous_lifetime ();
     577              :     }
     578           89 :   if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
     579              :     {
     580           89 :       return Lifetime::static_lifetime ();
     581              :     }
     582            0 :   rust_unreachable ();
     583              : }
     584              : 
     585              : WARN_UNUSED_RESULT tl::optional<TyTy::Region>
     586        29419 : TypeCheckContext::lookup_and_resolve_lifetime (
     587              :   const HIR::Lifetime &lifetime) const
     588              : {
     589        29419 :   auto maybe_interned = lookup_lifetime (lifetime);
     590        29419 :   if (!maybe_interned)
     591            6 :     return tl::nullopt;
     592              : 
     593        29413 :   return get_lifetime_resolver ().resolve (maybe_interned.value ());
     594              : }
     595              : void
     596           15 : TypeCheckContext::intern_and_insert_lifetime (const HIR::Lifetime &lifetime)
     597              : {
     598           15 :   get_lifetime_resolver ().insert_mapping (intern_lifetime (lifetime));
     599           15 : }
     600              : 
     601              : WARN_UNUSED_RESULT std::vector<TyTy::Region>
     602         9243 : TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
     603              : {
     604         9243 :   std::vector<TyTy::Region> regions;
     605         9272 :   for (const auto &lifetime : args.get_lifetime_args ())
     606              :     {
     607           30 :       auto resolved = lookup_and_resolve_lifetime (lifetime);
     608           30 :       if (!resolved)
     609              :         {
     610            1 :           rust_error_at (lifetime.get_locus (), "unresolved lifetime");
     611            1 :           return {};
     612              :         }
     613           29 :       regions.push_back (*resolved);
     614              :     }
     615         9242 :   return regions;
     616         9243 : }
     617              : 
     618              : bool
     619            8 : TypeCheckContext::compute_ambigious_op_overload (HirId id,
     620              :                                                  DeferredOpOverload &op)
     621              : {
     622            8 :   rust_debug ("attempting resolution of op overload: %s",
     623              :               op.predicate.as_string ().c_str ());
     624              : 
     625            8 :   TyTy::BaseType *lhs = nullptr;
     626            8 :   bool ok = lookup_type (op.op.get_lvalue_mappings ().get_hirid (), &lhs);
     627            8 :   rust_assert (ok);
     628              : 
     629            8 :   TyTy::BaseType *rhs = nullptr;
     630            8 :   if (op.op.has_rvalue_mappings ())
     631              :     {
     632            8 :       bool ok = lookup_type (op.op.get_rvalue_mappings ().get_hirid (), &rhs);
     633            8 :       rust_assert (ok);
     634              :     }
     635              : 
     636            8 :   TypeCheckExpr::ResolveOpOverload (op.lang_item_type, op.op, lhs, rhs,
     637            8 :                                     op.specified_segment);
     638              : 
     639            8 :   return true;
     640              : }
     641              : 
     642              : void
     643         4129 : TypeCheckContext::compute_inference_variables (bool emit_error)
     644              : {
     645         4129 :   iterate_deferred_operator_overloads (
     646         4129 :     [&] (HirId id, DeferredOpOverload &op) mutable -> bool {
     647            8 :       return compute_ambigious_op_overload (id, op);
     648              :     });
     649              : 
     650         4129 :   iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
     651       452058 :     return compute_infer_var (id, ty, emit_error);
     652              :   });
     653         4129 : }
     654              : 
     655              : bool
     656       452058 : TypeCheckContext::compute_infer_var (HirId id, TyTy::BaseType *ty,
     657              :                                      bool emit_error)
     658              : {
     659       452058 :   auto &mappings = Analysis::Mappings::get ();
     660              : 
     661              :   // nothing to do
     662       452058 :   if (ty->get_kind () != TyTy::TypeKind::INFER)
     663              :     return true;
     664              : 
     665         1830 :   TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
     666         1830 :   TyTy::BaseType *default_type;
     667              : 
     668         1830 :   rust_debug_loc (mappings.lookup_location (id),
     669              :                   "trying to default infer-var: %s",
     670         1830 :                   infer_var->as_string ().c_str ());
     671         1830 :   bool ok = infer_var->default_type (&default_type);
     672         1830 :   if (!ok)
     673              :     {
     674           12 :       if (emit_error)
     675           12 :         rust_error_at (mappings.lookup_location (id), ErrorCode::E0282,
     676              :                        "type annotations needed");
     677           12 :       return true;
     678              :     }
     679              : 
     680         1818 :   auto result
     681         1818 :     = unify_site (id, TyTy::TyWithLocation (ty),
     682         1818 :                   TyTy::TyWithLocation (default_type), UNDEF_LOCATION);
     683         1818 :   rust_assert (result);
     684         1818 :   rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
     685         1818 :   result->set_ref (id);
     686         1818 :   insert_implicit_type (id, result);
     687              : 
     688         1818 :   return true;
     689              : }
     690              : 
     691              : TyTy::VarianceAnalysis::CrateCtx &
     692         7965 : TypeCheckContext::get_variance_analysis_ctx ()
     693              : {
     694         7965 :   return variance_analysis_ctx;
     695              : }
     696              : 
     697              : // TypeCheckContextItem
     698              : 
     699         9143 : TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
     700              : 
     701         6835 : TypeCheckContextItem::Item::Item (HIR::ImplBlock *impl_block,
     702              :                                   HIR::Function *item)
     703         6835 :   : impl_item ({impl_block, item})
     704         6835 : {}
     705              : 
     706          855 : TypeCheckContextItem::Item::Item (HIR::TraitItemFunc *trait_item)
     707          855 :   : trait_item (trait_item)
     708          855 : {}
     709              : 
     710         6326 : TypeCheckContextItem::TypeCheckContextItem (HIR::Function *item)
     711         6326 :   : type (ItemType::ITEM), item (item)
     712         6326 : {}
     713              : 
     714         6835 : TypeCheckContextItem::TypeCheckContextItem (HIR::ImplBlock &impl_block,
     715         6835 :                                             HIR::Function *item)
     716         6835 :   : type (ItemType::IMPL_ITEM), item (&impl_block, item)
     717         6835 : {}
     718              : 
     719          855 : TypeCheckContextItem::TypeCheckContextItem (HIR::TraitItemFunc *trait_item)
     720          855 :   : type (ItemType::TRAIT_ITEM), item (trait_item)
     721          855 : {}
     722              : 
     723        18487 : TypeCheckContextItem::TypeCheckContextItem (const TypeCheckContextItem &other)
     724        18487 :   : type (other.type), item (other.item)
     725              : {
     726        18487 :   switch (other.type)
     727              :     {
     728              :     case ITEM:
     729              :       item.item = other.item.item;
     730              :       break;
     731              : 
     732         9784 :     case IMPL_ITEM:
     733         9784 :       item.impl_item = other.item.impl_item;
     734         9784 :       break;
     735              : 
     736              :     case TRAIT_ITEM:
     737              :       item.trait_item = other.item.trait_item;
     738              :       break;
     739              : 
     740            0 :     case ERROR:
     741            0 :       item.item = nullptr;
     742            0 :       break;
     743              :     }
     744        18487 : }
     745              : 
     746         2817 : TypeCheckContextItem::TypeCheckContextItem ()
     747         2817 :   : type (ItemType::ERROR), item (static_cast<HIR::Function *> (nullptr))
     748         2817 : {}
     749              : 
     750              : TypeCheckContextItem &
     751         2809 : TypeCheckContextItem::operator= (const TypeCheckContextItem &other)
     752              : {
     753         2809 :   type = other.type;
     754         2809 :   switch (other.type)
     755              :     {
     756          630 :     case ITEM:
     757          630 :       item.item = other.item.item;
     758          630 :       break;
     759              : 
     760         2065 :     case IMPL_ITEM:
     761         2065 :       item.impl_item = other.item.impl_item;
     762         2065 :       break;
     763              : 
     764          114 :     case TRAIT_ITEM:
     765          114 :       item.trait_item = other.item.trait_item;
     766          114 :       break;
     767              : 
     768            0 :     case ERROR:
     769            0 :       item.item = nullptr;
     770            0 :       break;
     771              :     }
     772              : 
     773         2809 :   return *this;
     774              : }
     775              : 
     776              : TypeCheckContextItem
     777         2817 : TypeCheckContextItem::get_error ()
     778              : {
     779         2817 :   return TypeCheckContextItem ();
     780              : }
     781              : 
     782              : bool
     783            0 : TypeCheckContextItem::is_error () const
     784              : {
     785            0 :   return type == ERROR;
     786              : }
     787              : 
     788              : HIR::Function *
     789           63 : TypeCheckContextItem::get_item ()
     790              : {
     791           63 :   rust_assert (get_type () == ItemType::ITEM);
     792           63 :   return item.item;
     793              : }
     794              : 
     795              : std::pair<HIR::ImplBlock *, HIR::Function *> &
     796          771 : TypeCheckContextItem::get_impl_item ()
     797              : {
     798          771 :   rust_assert (get_type () == ItemType::IMPL_ITEM);
     799          771 :   return item.impl_item;
     800              : }
     801              : 
     802              : HIR::TraitItemFunc *
     803            1 : TypeCheckContextItem::get_trait_item ()
     804              : {
     805            1 :   rust_assert (get_type () == ItemType::TRAIT_ITEM);
     806            1 :   return item.trait_item;
     807              : }
     808              : 
     809              : TypeCheckContextItem::ItemType
     810         5245 : TypeCheckContextItem::get_type () const
     811              : {
     812         5245 :   return type;
     813              : }
     814              : 
     815              : TyTy::FnType *
     816           64 : TypeCheckContextItem::get_context_type ()
     817              : {
     818           64 :   auto &context = *TypeCheckContext::get ();
     819              : 
     820           64 :   HirId reference = UNKNOWN_HIRID;
     821           64 :   switch (get_type ())
     822              :     {
     823           63 :     case ITEM:
     824           63 :       reference = get_item ()->get_mappings ().get_hirid ();
     825           63 :       break;
     826              : 
     827            0 :     case IMPL_ITEM:
     828            0 :       reference = get_impl_item ().second->get_mappings ().get_hirid ();
     829            0 :       break;
     830              : 
     831            1 :     case TRAIT_ITEM:
     832            1 :       reference = get_trait_item ()->get_mappings ().get_hirid ();
     833            1 :       break;
     834              : 
     835            0 :     case ERROR:
     836            0 :       rust_unreachable ();
     837              :       return nullptr;
     838              :     }
     839              : 
     840           64 :   rust_assert (reference != UNKNOWN_HIRID);
     841              : 
     842           64 :   TyTy::BaseType *lookup = nullptr;
     843           64 :   bool ok = context.lookup_type (reference, &lookup);
     844           64 :   rust_assert (ok);
     845           64 :   rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
     846           64 :   return static_cast<TyTy::FnType *> (lookup);
     847              : }
     848              : 
     849              : DefId
     850         2853 : TypeCheckContextItem::get_defid () const
     851              : {
     852         2853 :   switch (get_type ())
     853              :     {
     854          744 :     case ITEM:
     855          744 :       return item.item->get_mappings ().get_defid ();
     856              : 
     857         1987 :     case IMPL_ITEM:
     858         1987 :       return item.impl_item.second->get_mappings ().get_defid ();
     859              : 
     860          114 :     case TRAIT_ITEM:
     861          114 :       return item.trait_item->get_mappings ().get_defid ();
     862              : 
     863            8 :     case ERROR:
     864            8 :       return UNKNOWN_DEFID;
     865              :     }
     866              : 
     867            0 :   return UNKNOWN_DEFID;
     868              : }
     869              : 
     870              : // TypeCheckBlockContextItem
     871              : 
     872         8079 : TypeCheckBlockContextItem::Item::Item (HIR::ImplBlock *b) : block (b) {}
     873              : 
     874         3680 : TypeCheckBlockContextItem::Item::Item (HIR::Trait *t) : trait (t) {}
     875              : 
     876         8079 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::ImplBlock *block)
     877         8079 :   : type (TypeCheckBlockContextItem::ItemType::IMPL_BLOCK), item (block)
     878         8079 : {}
     879              : 
     880         3680 : TypeCheckBlockContextItem::TypeCheckBlockContextItem (HIR::Trait *trait)
     881         3680 :   : type (TypeCheckBlockContextItem::ItemType::TRAIT), item (trait)
     882         3680 : {}
     883              : 
     884              : bool
     885            0 : TypeCheckBlockContextItem::is_impl_block () const
     886              : {
     887            0 :   return type == IMPL_BLOCK;
     888              : }
     889              : 
     890              : bool
     891          845 : TypeCheckBlockContextItem::is_trait_block () const
     892              : {
     893          845 :   return type == TRAIT;
     894              : }
     895              : 
     896              : HIR::ImplBlock &
     897          148 : TypeCheckBlockContextItem::get_impl_block ()
     898              : {
     899          148 :   return *(item.block);
     900              : }
     901              : 
     902              : HIR::Trait &
     903          697 : TypeCheckBlockContextItem::get_trait ()
     904              : {
     905          697 :   return *(item.trait);
     906              : }
     907              : 
     908              : } // namespace Resolver
     909              : } // 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.