LCOV - code coverage report
Current view: top level - gcc/rust/resolve - rust-name-resolver.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 3.9 % 359 14
Test Date: 2026-02-28 14:20:25 Functions: 5.4 % 56 3
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-name-resolver.h"
      20              : #include "rust-ast-full.h"
      21              : 
      22              : // for flag_name_resolution_2_0
      23              : #include "options.h"
      24              : 
      25              : namespace Rust {
      26              : namespace Resolver {
      27              : 
      28            0 : Rib::Rib (CrateNum crateNum, NodeId node_id)
      29            0 :   : crate_num (crateNum), node_id (node_id)
      30            0 : {}
      31              : 
      32              : void
      33            0 : Rib::insert_name (
      34              :   const CanonicalPath &path, NodeId id, location_t locus, bool shadow,
      35              :   ItemType type,
      36              :   std::function<void (const CanonicalPath &, NodeId, location_t)> dup_cb)
      37              : {
      38            0 :   auto it = path_mappings.find (path);
      39            0 :   bool path_already_exists = it != path_mappings.end ();
      40            0 :   if (path_already_exists && !shadow)
      41              :     {
      42            0 :       const auto &decl = decls_within_rib.find (it->second);
      43            0 :       if (decl != decls_within_rib.end ())
      44            0 :         dup_cb (path, it->second, decl->second);
      45              :       else
      46            0 :         dup_cb (path, it->second, locus);
      47              : 
      48            0 :       return;
      49              :     }
      50              : 
      51            0 :   path_mappings[path] = id;
      52            0 :   reverse_path_mappings.insert ({id, path});
      53            0 :   decls_within_rib.insert ({id, locus});
      54            0 :   references[id] = {};
      55            0 :   decl_type_mappings.insert ({id, type});
      56              : }
      57              : 
      58              : bool
      59            0 : Rib::lookup_name (const CanonicalPath &ident, NodeId *id)
      60              : {
      61            0 :   auto it = path_mappings.find (ident);
      62            0 :   if (it == path_mappings.end ())
      63              :     return false;
      64              : 
      65            0 :   *id = it->second;
      66            0 :   return true;
      67              : }
      68              : 
      69              : void
      70            0 : Rib::clear_name (const CanonicalPath &ident, NodeId id)
      71              : {
      72            0 :   auto ii = path_mappings.find (ident);
      73            0 :   if (ii != path_mappings.end ())
      74            0 :     path_mappings.erase (ii);
      75              : 
      76            0 :   auto ij = reverse_path_mappings.find (id);
      77            0 :   if (ij != reverse_path_mappings.end ())
      78            0 :     reverse_path_mappings.erase (ij);
      79              : 
      80            0 :   auto ik = decls_within_rib.find (id);
      81            0 :   if (ik != decls_within_rib.end ())
      82            0 :     decls_within_rib.erase (ik);
      83            0 : }
      84              : 
      85              : void
      86            0 : Rib::append_reference_for_def (NodeId def, NodeId ref)
      87              : {
      88            0 :   references[def].insert (ref);
      89            0 : }
      90              : 
      91              : bool
      92            0 : Rib::have_references_for_node (NodeId def) const
      93              : {
      94            0 :   auto it = references.find (def);
      95            0 :   if (it == references.end ())
      96              :     return false;
      97              : 
      98            0 :   return !it->second.empty ();
      99              : }
     100              : 
     101              : bool
     102            0 : Rib::decl_was_declared_here (NodeId def) const
     103              : {
     104            0 :   for (auto &it : decls_within_rib)
     105              :     {
     106            0 :       if (it.first == def)
     107            0 :         return true;
     108              :     }
     109              :   return false;
     110              : }
     111              : 
     112              : bool
     113            0 : Rib::lookup_decl_type (NodeId def, ItemType *type) const
     114              : {
     115            0 :   auto it = decl_type_mappings.find (def);
     116            0 :   if (it == decl_type_mappings.end ())
     117              :     return false;
     118              : 
     119            0 :   *type = it->second;
     120            0 :   return true;
     121              : }
     122              : 
     123              : void
     124            0 : Rib::debug () const
     125              : {
     126            0 :   fprintf (stderr, "%s\n", debug_str ().c_str ());
     127            0 : }
     128              : 
     129              : std::string
     130            0 : Rib::debug_str () const
     131              : {
     132            0 :   std::string buffer;
     133            0 :   for (const auto &it : path_mappings)
     134              :     {
     135            0 :       buffer += it.first.get () + "=" + std::to_string (it.second);
     136            0 :       buffer += ",";
     137              :     }
     138            0 :   return "{" + buffer + "}";
     139            0 : }
     140              : 
     141        18040 : Scope::Scope (CrateNum crate_num) : crate_num (crate_num) {}
     142              : 
     143              : void
     144            0 : Scope::insert (
     145              :   const CanonicalPath &ident, NodeId id, location_t locus, bool shadow,
     146              :   Rib::ItemType type,
     147              :   std::function<void (const CanonicalPath &, NodeId, location_t)> dup_cb)
     148              : {
     149            0 :   peek ()->insert_name (ident, id, locus, shadow, type, dup_cb);
     150            0 : }
     151              : 
     152              : void
     153            0 : Scope::insert (const CanonicalPath &ident, NodeId id, location_t locus,
     154              :                Rib::ItemType type)
     155              : {
     156            0 :   peek ()->insert_name (ident, id, locus, true, type,
     157            0 :                         [] (const CanonicalPath &, NodeId, location_t) -> void {
     158              :                         });
     159            0 : }
     160              : 
     161              : bool
     162            0 : Scope::lookup (const CanonicalPath &ident, NodeId *id)
     163              : {
     164            0 :   NodeId lookup = UNKNOWN_NODEID;
     165            0 :   iterate ([&] (Rib *r) mutable -> bool {
     166            0 :     if (r->lookup_name (ident, &lookup))
     167            0 :       return false;
     168              :     return true;
     169              :   });
     170              : 
     171            0 :   *id = lookup;
     172            0 :   return lookup != UNKNOWN_NODEID;
     173              : }
     174              : 
     175              : bool
     176            0 : Scope::lookup_decl_type (NodeId id, Rib::ItemType *type)
     177              : {
     178            0 :   bool found = false;
     179            0 :   iterate ([&] (const Rib *r) -> bool {
     180            0 :     if (r->decl_was_declared_here (id))
     181              :       {
     182            0 :         bool ok = r->lookup_decl_type (id, type);
     183            0 :         rust_assert (ok);
     184            0 :         found = true;
     185            0 :         return false;
     186              :       }
     187              :     return true;
     188              :   });
     189            0 :   return found;
     190              : }
     191              : 
     192              : bool
     193            0 : Scope::lookup_rib_for_decl (NodeId id, const Rib **rib)
     194              : {
     195            0 :   bool found = false;
     196            0 :   iterate ([&] (const Rib *r) -> bool {
     197            0 :     if (r->decl_was_declared_here (id))
     198              :       {
     199            0 :         *rib = r;
     200            0 :         found = true;
     201            0 :         return false;
     202              :       }
     203              :     return true;
     204              :   });
     205            0 :   return found;
     206              : }
     207              : 
     208              : void
     209            0 : Scope::iterate (std::function<bool (Rib *)> cb)
     210              : {
     211            0 :   for (auto it = stack.rbegin (); it != stack.rend (); ++it)
     212              :     {
     213            0 :       if (!cb (*it))
     214            0 :         return;
     215              :     }
     216              : }
     217              : 
     218              : void
     219            0 : Scope::iterate (std::function<bool (const Rib *)> cb) const
     220              : {
     221            0 :   for (auto it = stack.rbegin (); it != stack.rend (); ++it)
     222              :     {
     223            0 :       if (!cb (*it))
     224            0 :         return;
     225              :     }
     226              : }
     227              : 
     228              : Rib *
     229            0 : Scope::peek ()
     230              : {
     231            0 :   return stack.back ();
     232              : }
     233              : 
     234              : void
     235            0 : Scope::push (NodeId id)
     236              : {
     237            0 :   stack.push_back (new Rib (get_crate_num (), id));
     238            0 : }
     239              : 
     240              : Rib *
     241            0 : Scope::pop ()
     242              : {
     243            0 :   Rib *r = peek ();
     244            0 :   stack.pop_back ();
     245            0 :   return r;
     246              : }
     247              : 
     248              : void
     249            0 : Scope::append_reference_for_def (NodeId refId, NodeId defId)
     250              : {
     251            0 :   bool ok = false;
     252            0 :   iterate ([&] (Rib *r) mutable -> bool {
     253            0 :     if (r->decl_was_declared_here (defId))
     254              :       {
     255            0 :         ok = true;
     256            0 :         r->append_reference_for_def (defId, refId);
     257              :       }
     258            0 :     return true;
     259              :   });
     260            0 :   rust_assert (ok);
     261            0 : }
     262              : 
     263              : bool
     264            0 : Scope::decl_was_declared_here (NodeId def) const
     265              : {
     266            0 :   bool found = false;
     267            0 :   iterate ([&] (const Rib *r) -> bool {
     268            0 :     if (r->decl_was_declared_here (def))
     269              :       {
     270            0 :         found = true;
     271            0 :         return false;
     272              :       }
     273              :     return true;
     274              :   });
     275            0 :   return found;
     276              : }
     277              : 
     278         4510 : Resolver::Resolver ()
     279         4510 :   : mappings (Analysis::Mappings::get ()), tyctx (TypeCheckContext::get ()),
     280         4510 :     name_scope (Scope (mappings.get_current_crate ())),
     281         4510 :     type_scope (Scope (mappings.get_current_crate ())),
     282         4510 :     label_scope (Scope (mappings.get_current_crate ())),
     283         4510 :     macro_scope (Scope (mappings.get_current_crate ())),
     284         4510 :     global_type_node_id (UNKNOWN_NODEID), unit_ty_node_id (UNKNOWN_NODEID)
     285         4510 : {}
     286              : 
     287              : Resolver *
     288        24814 : Resolver::get ()
     289              : {
     290        24814 :   static Resolver *instance;
     291        24814 :   if (instance == nullptr)
     292         4510 :     instance = new Resolver ();
     293              : 
     294        24814 :   return instance;
     295              : }
     296              : 
     297              : void
     298            0 : Resolver::push_new_name_rib (Rib *r)
     299              : {
     300            0 :   rust_assert (name_ribs.find (r->get_node_id ()) == name_ribs.end ());
     301            0 :   name_ribs[r->get_node_id ()] = r;
     302            0 : }
     303              : 
     304              : void
     305            0 : Resolver::push_new_type_rib (Rib *r)
     306              : {
     307            0 :   if (type_ribs.size () == 0)
     308            0 :     global_type_node_id = r->get_node_id ();
     309              : 
     310            0 :   rust_assert (type_ribs.find (r->get_node_id ()) == type_ribs.end ());
     311            0 :   type_ribs[r->get_node_id ()] = r;
     312            0 : }
     313              : 
     314              : void
     315            0 : Resolver::push_new_label_rib (Rib *r)
     316              : {
     317            0 :   rust_assert (label_ribs.find (r->get_node_id ()) == label_ribs.end ());
     318            0 :   label_ribs[r->get_node_id ()] = r;
     319            0 : }
     320              : 
     321              : void
     322            0 : Resolver::push_new_macro_rib (Rib *r)
     323              : {
     324            0 :   rust_assert (label_ribs.find (r->get_node_id ()) == label_ribs.end ());
     325            0 :   macro_ribs[r->get_node_id ()] = r;
     326            0 : }
     327              : 
     328              : bool
     329            0 : Resolver::find_name_rib (NodeId id, Rib **rib)
     330              : {
     331            0 :   auto it = name_ribs.find (id);
     332            0 :   if (it == name_ribs.end ())
     333              :     return false;
     334              : 
     335            0 :   *rib = it->second;
     336            0 :   return true;
     337              : }
     338              : 
     339              : bool
     340            0 : Resolver::find_type_rib (NodeId id, Rib **rib)
     341              : {
     342            0 :   auto it = type_ribs.find (id);
     343            0 :   if (it == type_ribs.end ())
     344              :     return false;
     345              : 
     346            0 :   *rib = it->second;
     347            0 :   return true;
     348              : }
     349              : 
     350              : bool
     351            0 : Resolver::find_macro_rib (NodeId id, Rib **rib)
     352              : {
     353            0 :   auto it = macro_ribs.find (id);
     354            0 :   if (it == macro_ribs.end ())
     355              :     return false;
     356              : 
     357            0 :   *rib = it->second;
     358            0 :   return true;
     359              : }
     360              : 
     361              : void
     362            0 : Resolver::insert_builtin_types (Rib *r)
     363              : {
     364            0 :   auto builtins = get_builtin_types ();
     365            0 :   for (auto &builtin : builtins)
     366              :     {
     367            0 :       CanonicalPath builtin_path
     368            0 :         = CanonicalPath::new_seg (builtin->get_node_id (),
     369            0 :                                   builtin->as_string ());
     370            0 :       r->insert_name (builtin_path, builtin->get_node_id (), BUILTINS_LOCATION,
     371              :                       false, Rib::ItemType::Type,
     372            0 :                       [] (const CanonicalPath &, NodeId, location_t) -> void {
     373              :                       });
     374            0 :     }
     375            0 : }
     376              : 
     377              : std::vector<AST::Type *> &
     378            0 : Resolver::get_builtin_types ()
     379              : {
     380            0 :   return builtins;
     381              : }
     382              : 
     383              : void
     384            0 : Resolver::generate_builtins ()
     385              : {
     386            0 :   auto u8
     387            0 :     = new TyTy::UintType (mappings.get_next_hir_id (), TyTy::UintType::U8);
     388            0 :   auto u16
     389            0 :     = new TyTy::UintType (mappings.get_next_hir_id (), TyTy::UintType::U16);
     390            0 :   auto u32
     391            0 :     = new TyTy::UintType (mappings.get_next_hir_id (), TyTy::UintType::U32);
     392            0 :   auto u64
     393            0 :     = new TyTy::UintType (mappings.get_next_hir_id (), TyTy::UintType::U64);
     394            0 :   auto u128
     395            0 :     = new TyTy::UintType (mappings.get_next_hir_id (), TyTy::UintType::U128);
     396            0 :   auto i8 = new TyTy::IntType (mappings.get_next_hir_id (), TyTy::IntType::I8);
     397            0 :   auto i16
     398            0 :     = new TyTy::IntType (mappings.get_next_hir_id (), TyTy::IntType::I16);
     399            0 :   auto i32
     400            0 :     = new TyTy::IntType (mappings.get_next_hir_id (), TyTy::IntType::I32);
     401            0 :   auto i64
     402            0 :     = new TyTy::IntType (mappings.get_next_hir_id (), TyTy::IntType::I64);
     403            0 :   auto i128
     404            0 :     = new TyTy::IntType (mappings.get_next_hir_id (), TyTy::IntType::I128);
     405            0 :   auto rbool = new TyTy::BoolType (mappings.get_next_hir_id ());
     406            0 :   auto f32
     407            0 :     = new TyTy::FloatType (mappings.get_next_hir_id (), TyTy::FloatType::F32);
     408            0 :   auto f64
     409            0 :     = new TyTy::FloatType (mappings.get_next_hir_id (), TyTy::FloatType::F64);
     410            0 :   auto usize = new TyTy::USizeType (mappings.get_next_hir_id ());
     411            0 :   auto isize = new TyTy::ISizeType (mappings.get_next_hir_id ());
     412            0 :   auto char_tyty = new TyTy::CharType (mappings.get_next_hir_id ());
     413            0 :   auto str = new TyTy::StrType (mappings.get_next_hir_id ());
     414            0 :   auto never = new TyTy::NeverType (mappings.get_next_hir_id ());
     415              : 
     416            0 :   setup_builtin ("u8", u8);
     417            0 :   setup_builtin ("u16", u16);
     418            0 :   setup_builtin ("u32", u32);
     419            0 :   setup_builtin ("u64", u64);
     420            0 :   setup_builtin ("u128", u128);
     421            0 :   setup_builtin ("i8", i8);
     422            0 :   setup_builtin ("i16", i16);
     423            0 :   setup_builtin ("i32", i32);
     424            0 :   setup_builtin ("i64", i64);
     425            0 :   setup_builtin ("i128", i128);
     426            0 :   setup_builtin ("bool", rbool);
     427            0 :   setup_builtin ("f32", f32);
     428            0 :   setup_builtin ("f64", f64);
     429            0 :   setup_builtin ("usize", usize);
     430            0 :   setup_builtin ("isize", isize);
     431            0 :   setup_builtin ("char", char_tyty);
     432            0 :   setup_builtin ("str", str);
     433              : 
     434              :   // never type
     435            0 :   NodeId never_node_id = setup_builtin ("!", never);
     436            0 :   set_never_type_node_id (never_node_id);
     437              : 
     438              :   // unit type ()
     439            0 :   TyTy::TupleType *unit_tyty = TyTy::TupleType::get_unit_type ();
     440            0 :   std::vector<std::unique_ptr<AST::Type> > elems;
     441            0 :   AST::TupleType *unit_type
     442            0 :     = new AST::TupleType (std::move (elems), BUILTINS_LOCATION);
     443            0 :   builtins.push_back (unit_type);
     444            0 :   tyctx->insert_builtin (unit_tyty->get_ref (), unit_type->get_node_id (),
     445              :                          unit_tyty);
     446            0 :   set_unit_type_node_id (unit_type->get_node_id ());
     447            0 : }
     448              : 
     449              : NodeId
     450            0 : Resolver::setup_builtin (const std::string &name, TyTy::BaseType *tyty)
     451              : {
     452            0 :   AST::PathIdentSegment seg (name, BUILTINS_LOCATION);
     453            0 :   auto typePath = ::std::unique_ptr<AST::TypePathSegment> (
     454            0 :     new AST::TypePathSegment (::std::move (seg), false, BUILTINS_LOCATION));
     455            0 :   ::std::vector< ::std::unique_ptr<AST::TypePathSegment> > segs;
     456            0 :   segs.push_back (::std::move (typePath));
     457            0 :   auto builtin_type
     458            0 :     = new AST::TypePath (::std::move (segs), BUILTINS_LOCATION, false);
     459            0 :   builtins.push_back (builtin_type);
     460            0 :   tyctx->insert_builtin (tyty->get_ref (), builtin_type->get_node_id (), tyty);
     461            0 :   mappings.insert_node_to_hir (builtin_type->get_node_id (), tyty->get_ref ());
     462            0 :   mappings.insert_canonical_path (
     463            0 :     builtin_type->get_node_id (),
     464            0 :     CanonicalPath::new_seg (builtin_type->get_node_id (), name));
     465              : 
     466            0 :   return builtin_type->get_node_id ();
     467            0 : }
     468              : 
     469              : void
     470            0 : Resolver::insert_resolved_name (NodeId refId, NodeId defId)
     471              : {
     472            0 :   rust_assert (!flag_name_resolution_2_0);
     473            0 :   rust_assert (resolved_names.find (refId) == resolved_names.end ());
     474              : 
     475            0 :   resolved_names[refId] = defId;
     476            0 :   get_name_scope ().append_reference_for_def (refId, defId);
     477            0 :   insert_captured_item (defId);
     478            0 : }
     479              : 
     480              : bool
     481            0 : Resolver::lookup_resolved_name (NodeId refId, NodeId *defId)
     482              : {
     483            0 :   rust_assert (!flag_name_resolution_2_0);
     484            0 :   auto it = resolved_names.find (refId);
     485            0 :   if (it == resolved_names.end ())
     486              :     return false;
     487              : 
     488            0 :   *defId = it->second;
     489            0 :   return true;
     490              : }
     491              : 
     492              : void
     493            0 : Resolver::insert_resolved_type (NodeId refId, NodeId defId)
     494              : {
     495            0 :   rust_assert (!flag_name_resolution_2_0);
     496            0 :   rust_assert (resolved_types.find (refId) == resolved_types.end ());
     497              : 
     498            0 :   resolved_types[refId] = defId;
     499            0 :   get_type_scope ().append_reference_for_def (refId, defId);
     500            0 : }
     501              : 
     502              : bool
     503            0 : Resolver::lookup_resolved_type (NodeId refId, NodeId *defId)
     504              : {
     505            0 :   rust_assert (!flag_name_resolution_2_0);
     506            0 :   auto it = resolved_types.find (refId);
     507            0 :   if (it == resolved_types.end ())
     508              :     return false;
     509              : 
     510            0 :   *defId = it->second;
     511            0 :   return true;
     512              : }
     513              : 
     514              : void
     515            0 : Resolver::insert_resolved_label (NodeId refId, NodeId defId)
     516              : {
     517            0 :   rust_assert (!flag_name_resolution_2_0);
     518            0 :   auto it = resolved_labels.find (refId);
     519            0 :   rust_assert (it == resolved_labels.end ());
     520              : 
     521            0 :   resolved_labels[refId] = defId;
     522            0 :   get_label_scope ().append_reference_for_def (refId, defId);
     523            0 : }
     524              : 
     525              : bool
     526            0 : Resolver::lookup_resolved_label (NodeId refId, NodeId *defId)
     527              : {
     528            0 :   rust_assert (!flag_name_resolution_2_0);
     529            0 :   auto it = resolved_labels.find (refId);
     530            0 :   if (it == resolved_labels.end ())
     531              :     return false;
     532              : 
     533            0 :   *defId = it->second;
     534            0 :   return true;
     535              : }
     536              : 
     537              : void
     538            0 : Resolver::insert_resolved_macro (NodeId refId, NodeId defId)
     539              : {
     540            0 :   rust_assert (!flag_name_resolution_2_0);
     541            0 :   auto it = resolved_macros.find (refId);
     542            0 :   rust_assert (it == resolved_macros.end ());
     543              : 
     544            0 :   resolved_labels[refId] = defId;
     545            0 :   get_label_scope ().append_reference_for_def (refId, defId);
     546            0 : }
     547              : 
     548              : bool
     549            0 : Resolver::lookup_resolved_macro (NodeId refId, NodeId *defId)
     550              : {
     551            0 :   rust_assert (!flag_name_resolution_2_0);
     552            0 :   auto it = resolved_macros.find (refId);
     553            0 :   if (it == resolved_macros.end ())
     554              :     return false;
     555              : 
     556            0 :   *defId = it->second;
     557            0 :   return true;
     558              : }
     559              : 
     560              : void
     561            0 : Resolver::insert_resolved_misc (NodeId refId, NodeId defId)
     562              : {
     563            0 :   rust_assert (!flag_name_resolution_2_0);
     564            0 :   auto it = misc_resolved_items.find (refId);
     565            0 :   rust_assert (it == misc_resolved_items.end ());
     566              : 
     567            0 :   misc_resolved_items[refId] = defId;
     568            0 : }
     569              : 
     570              : bool
     571            0 : Resolver::lookup_resolved_misc (NodeId refId, NodeId *defId)
     572              : {
     573            0 :   rust_assert (!flag_name_resolution_2_0);
     574            0 :   auto it = misc_resolved_items.find (refId);
     575            0 :   if (it == misc_resolved_items.end ())
     576              :     return false;
     577              : 
     578            0 :   *defId = it->second;
     579            0 :   return true;
     580              : }
     581              : 
     582              : void
     583            0 : Resolver::push_closure_context (NodeId closure_expr_id)
     584              : {
     585            0 :   auto it = closures_capture_mappings.find (closure_expr_id);
     586            0 :   rust_assert (it == closures_capture_mappings.end ());
     587              : 
     588            0 :   closures_capture_mappings.insert ({closure_expr_id, {}});
     589            0 :   closure_context.push_back (closure_expr_id);
     590            0 : }
     591              : 
     592              : void
     593            0 : Resolver::pop_closure_context ()
     594              : {
     595            0 :   rust_assert (!closure_context.empty ());
     596            0 :   closure_context.pop_back ();
     597            0 : }
     598              : 
     599              : void
     600            0 : Resolver::insert_captured_item (NodeId id)
     601              : {
     602              :   // nothing to do unless we are in a closure context
     603            0 :   if (closure_context.empty ())
     604            0 :     return;
     605              : 
     606              :   // check that this is a VAR_DECL?
     607            0 :   Scope &name_scope = get_name_scope ();
     608            0 :   Rib::ItemType type = Rib::ItemType::Unknown;
     609            0 :   bool found = name_scope.lookup_decl_type (id, &type);
     610            0 :   if (!found)
     611              :     return;
     612              : 
     613              :   // RIB Function { let a, let b } id = 1;
     614              :   //   RIB Closure { let c } id = 2;
     615              :   //     RIB IfStmt { <bind a>} id = 3;
     616              :   //   RIB ... { ... } id = 4
     617              :   //
     618              :   // if we have a resolved_node_id of 'a' and the current rib is '3' we know
     619              :   // this is binding exists in a rib with id < the closure rib id, other wise
     620              :   // its just a normal binding and we don't care
     621              :   //
     622              :   // Problem the node id's dont work like this because the inner most items are
     623              :   // created first so this means the root will have a larger id and a simple
     624              :   // less than or greater than check wont work for more complex scoping cases
     625              :   // but we can use our current rib context to figure this out by checking if
     626              :   // the rib id the decl we care about exists prior to the rib for the closure
     627              :   // id
     628              : 
     629            0 :   const Rib *r = nullptr;
     630            0 :   bool ok = name_scope.lookup_rib_for_decl (id, &r);
     631            0 :   rust_assert (ok);
     632            0 :   NodeId decl_rib_node_id = r->get_node_id ();
     633              : 
     634              :   // iterate the closure context and add in the mapping for all to handle the
     635              :   // case of nested closures
     636            0 :   for (auto &closure_expr_id : closure_context)
     637              :     {
     638            0 :       if (!decl_needs_capture (decl_rib_node_id, closure_expr_id, name_scope))
     639            0 :         continue;
     640              : 
     641              :       // is this a valid binding to take
     642            0 :       bool is_var_decl_p = type == Rib::ItemType::Var;
     643            0 :       if (!is_var_decl_p)
     644              :         {
     645              :           // FIXME is this an error case?
     646            0 :           return;
     647              :         }
     648              : 
     649              :       // append it to the context info
     650            0 :       auto it = closures_capture_mappings.find (closure_expr_id);
     651            0 :       rust_assert (it != closures_capture_mappings.end ());
     652              : 
     653            0 :       it->second.insert (id);
     654              :     }
     655              : }
     656              : 
     657              : bool
     658            0 : Resolver::decl_needs_capture (NodeId decl_rib_node_id,
     659              :                               NodeId closure_rib_node_id, const Scope &scope)
     660              : {
     661            0 :   for (const auto &rib : scope.get_context ())
     662              :     {
     663            0 :       bool rib_is_closure = rib->get_node_id () == closure_rib_node_id;
     664            0 :       bool rib_is_decl = rib->get_node_id () == decl_rib_node_id;
     665            0 :       if (rib_is_closure)
     666              :         return false;
     667            0 :       else if (rib_is_decl)
     668              :         return true;
     669              :     }
     670              :   return false;
     671              : }
     672              : 
     673              : const std::set<NodeId> &
     674            0 : Resolver::get_captures (NodeId id) const
     675              : {
     676            0 :   rust_assert (!flag_name_resolution_2_0);
     677              : 
     678            0 :   auto it = closures_capture_mappings.find (id);
     679            0 :   rust_assert (it != closures_capture_mappings.end ());
     680            0 :   return it->second;
     681              : }
     682              : 
     683              : } // namespace Resolver
     684              : } // 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.