LCOV - code coverage report
Current view: top level - gcc/rust/resolve - rust-name-resolver.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.3 % 356 318
Test Date: 2025-04-19 15:48:17 Functions: 87.5 % 56 49
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

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

Generated by: LCOV version 2.1-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.