LCOV - code coverage report
Current view: top level - gcc/rust/resolve - rust-toplevel-name-resolver-2.0.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.8 % 270 256
Test Date: 2026-09-12 16:25:28 Functions: 100.0 % 62 62
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-toplevel-name-resolver-2.0.h"
      20              : #include "input.h"
      21              : #include "optional.h"
      22              : #include "rust-ast-full.h"
      23              : #include "rust-hir-map.h"
      24              : #include "rust-attribute-values.h"
      25              : 
      26              : namespace Rust {
      27              : namespace Resolver2_0 {
      28              : 
      29        16139 : TopLevel::TopLevel (NameResolutionContext &resolver)
      30        16139 :   : DefaultResolver (resolver), dirty (false)
      31        16139 : {}
      32              : 
      33              : template <typename T>
      34              : void
      35         7621 : TopLevel::insert_enum_variant_or_error_out (const Identifier &identifier,
      36              :                                             const T &node, bool is_also_value)
      37              : {
      38         7621 :   insert_enum_variant_or_error_out (identifier, node.get_locus (),
      39         7621 :                                     node.get_node_id (), is_also_value);
      40         7621 : }
      41              : 
      42              : void
      43      1277661 : TopLevel::check_multiple_insertion_error (
      44              :   tl::expected<NodeId, DuplicateNameError> result, const Identifier &identifier,
      45              :   const location_t &locus, const NodeId node_id)
      46              : {
      47      1277661 :   if (result)
      48        83438 :     dirty = true;
      49      1194223 :   else if (result.error ().existing != node_id)
      50              :     {
      51           32 :       rich_location rich_loc (line_table, locus);
      52           32 :       rich_loc.add_range (node_locations[result.error ().existing]);
      53           32 :       auto &mappings = Analysis::Mappings::get ();
      54           32 :       ErrorCode code;
      55           32 :       if (mappings.is_extern_crate (node_id)
      56           32 :           && mappings.is_extern_crate (result.error ().existing))
      57              :         code = ErrorCode::E0259;
      58           24 :       else if (mappings.is_extern_crate (node_id)
      59           24 :                || mappings.is_extern_crate (result.error ().existing))
      60              :         code = ErrorCode::E0260;
      61              :       else
      62              :         code = ErrorCode::E0428;
      63              : 
      64           32 :       rust_error_at (rich_loc, code, "%qs defined multiple times",
      65           32 :                      identifier.as_string ().c_str ());
      66           32 :     }
      67      1277661 : }
      68              : void
      69         7621 : TopLevel::insert_enum_variant_or_error_out (const Identifier &identifier,
      70              :                                             const location_t &locus,
      71              :                                             const NodeId node_id,
      72              :                                             bool is_also_value)
      73              : {
      74              :   // keep track of each node's location to provide useful errors
      75         7621 :   node_locations.emplace (node_id, locus);
      76              : 
      77         7621 :   auto result = ctx.insert_variant (identifier, node_id, is_also_value);
      78        13843 :   check_multiple_insertion_error (result, identifier, locus, node_id);
      79         7621 : }
      80              : 
      81              : template <typename T>
      82              : void
      83      1262252 : TopLevel::insert_or_error_out (const Identifier &identifier, const T &node,
      84              :                                Namespace ns)
      85              : {
      86      1262252 :   insert_or_error_out (identifier, node.get_locus (), node.get_node_id (), ns);
      87      1262252 : }
      88              : 
      89              : void
      90      1270040 : TopLevel::insert_or_error_out (const Identifier &identifier,
      91              :                                const location_t &locus, const NodeId &node_id,
      92              :                                Namespace ns)
      93              : {
      94              :   // keep track of each node's location to provide useful errors
      95      1270040 :   node_locations.emplace (node_id, locus);
      96              : 
      97      1270040 :   auto result = ctx.insert (identifier, node_id, ns);
      98      2458041 :   check_multiple_insertion_error (result, identifier, locus, node_id);
      99      1270040 : }
     100              : 
     101              : void
     102        16139 : TopLevel::go (AST::Crate &crate)
     103              : {
     104              :   // we do not include builtin types in the top-level definition collector, as
     105              :   // they are not used until `Late`. furthermore, we run this visitor multiple
     106              :   // times in a row in a fixed-point fashion, so it would make the code
     107              :   // responsible for this ugly and perfom a lot of error checking.
     108              : 
     109        16139 :   visit (crate);
     110              : 
     111        16139 :   if (Analysis::Mappings::get ().lookup_glob_container (crate.get_node_id ())
     112        16139 :       == tl::nullopt)
     113         4960 :     Analysis::Mappings::get ().insert_glob_container (crate.get_node_id (),
     114              :                                                       &crate);
     115        16139 : }
     116              : 
     117              : void
     118        12955 : TopLevel::visit (AST::Module &module)
     119              : {
     120        12955 :   if (Analysis::Mappings::get ().lookup_glob_container (module.get_node_id ())
     121        12955 :       == tl::nullopt)
     122         1551 :     Analysis::Mappings::get ().insert_glob_container (module.get_node_id (),
     123              :                                                       &module);
     124              : 
     125        12955 :   insert_or_error_out (module.get_name (), module, Namespace::Types);
     126              : 
     127        12955 :   Analysis::Mappings::get ().insert_module_id (module.get_node_id ());
     128              : 
     129        12955 :   DefaultResolver::visit (module);
     130        12955 : }
     131              : 
     132              : void
     133        18150 : TopLevel::visit (AST::Trait &trait)
     134              : {
     135        18150 :   insert_or_error_out (trait.get_identifier (), trait, Namespace::Types);
     136              : 
     137        18150 :   DefaultResolver::visit (trait);
     138        18150 : }
     139              : 
     140              : void
     141          174 : TopLevel::visit (AST::ExternCrate &crate)
     142              : {
     143          174 :   auto &name = crate.has_as_clause () ? crate.get_as_clause ()
     144          174 :                                       : crate.get_referenced_crate ();
     145          174 :   Analysis::Mappings::get ().insert_extern_crate_id (crate.get_node_id ());
     146          522 :   insert_or_error_out (name, crate, Namespace::Types);
     147              : 
     148          174 :   DefaultResolver::visit (crate);
     149          174 : }
     150              : 
     151              : void
     152       258951 : TopLevel::maybe_insert_big_self (AST::Impl &impl)
     153              : {
     154       517902 :   insert_or_error_out (Identifier ("Self", impl.get_type ().get_locus ()),
     155       258951 :                        impl.get_type (), Namespace::Types);
     156       258951 : }
     157              : 
     158              : void
     159         3928 : TopLevel::visit (AST::TraitItemType &trait_item)
     160              : {
     161        11784 :   insert_or_error_out (trait_item.get_identifier ().as_string (), trait_item,
     162              :                        Namespace::Types);
     163              : 
     164         3928 :   DefaultResolver::visit (trait_item);
     165         3928 : }
     166              : 
     167              : template <typename PROC_MACRO>
     168              : static void
     169          504 : insert_macros (std::vector<PROC_MACRO> &macros, NameResolutionContext &ctx)
     170              : {
     171          504 :   for (auto &macro : macros)
     172              :     {
     173            0 :       auto res = ctx.macros.insert (macro.get_name (), macro.get_node_id ());
     174              : 
     175            0 :       if (!res && res.error ().existing != macro.get_node_id ())
     176              :         {
     177            0 :           rust_error_at (UNKNOWN_LOCATION, ErrorCode::E0428,
     178              :                          "macro %qs defined multiple times",
     179            0 :                          macro.get_name ().c_str ());
     180              :         }
     181              :     }
     182          504 : }
     183              : 
     184              : void
     185          171 : TopLevel::visit_extern_crate (AST::ExternCrate &extern_crate, AST::Crate &crate,
     186              :                               CrateNum num)
     187              : {
     188          171 :   auto &mappings = Analysis::Mappings::get ();
     189              : 
     190          171 :   auto attribute_macros = mappings.lookup_attribute_proc_macros (num);
     191              : 
     192          171 :   auto bang_macros = mappings.lookup_bang_proc_macros (num);
     193              : 
     194          171 :   auto derive_macros = mappings.lookup_derive_proc_macros (num);
     195              : 
     196              :   // TODO: Find a way to keep this part clean without the double dispatch.
     197          171 :   if (derive_macros.has_value ())
     198              :     {
     199          168 :       insert_macros (derive_macros.value (), ctx);
     200          168 :       for (auto &macro : derive_macros.value ())
     201            0 :         mappings.insert_derive_proc_macro_def (macro);
     202              :     }
     203          171 :   if (attribute_macros.has_value ())
     204              :     {
     205          168 :       insert_macros (attribute_macros.value (), ctx);
     206          168 :       for (auto &macro : attribute_macros.value ())
     207            0 :         mappings.insert_attribute_proc_macro_def (macro);
     208              :     }
     209          171 :   if (bang_macros.has_value ())
     210              :     {
     211          168 :       insert_macros (bang_macros.value (), ctx);
     212          168 :       for (auto &macro : bang_macros.value ())
     213            0 :         mappings.insert_bang_proc_macro_def (macro);
     214              :     }
     215              : 
     216              :   // We do *NOT* visit the crate because loaded crates are resolved
     217              :   // independently.
     218          171 : }
     219              : 
     220              : static bool
     221        30559 : is_macro_export (AST::MacroRulesDefinition &def)
     222              : {
     223        74026 :   for (const auto &attr : def.get_outer_attrs ())
     224        44742 :     if (attr.get_path ().as_string () == Values::Attributes::MACRO_EXPORT)
     225        30559 :       return true;
     226              : 
     227              :   return false;
     228              : }
     229              : 
     230              : void
     231        30559 : TopLevel::visit (AST::MacroRulesDefinition &macro)
     232              : {
     233              :   // we do not insert macros in the current rib as that needs to be done in the
     234              :   // textual scope of the Early pass. we only insert them in the root of the
     235              :   // crate if they are marked with #[macro_export]. The execption to this is
     236              :   // macros 2.0, which get resolved and inserted like regular items.
     237              : 
     238        30559 :   if (is_macro_export (macro))
     239              :     {
     240         3825 :       auto res = ctx.macros.insert_at_root (macro.get_rule_name (),
     241         1275 :                                             macro.get_node_id ());
     242         1275 :       if (!res && res.error ().existing != macro.get_node_id ())
     243              :         {
     244              :           // TODO: Factor this
     245            0 :           rich_location rich_loc (line_table, macro.get_locus ());
     246            0 :           rich_loc.add_range (node_locations[res.error ().existing]);
     247              : 
     248            0 :           rust_error_at (rich_loc, ErrorCode::E0428,
     249              :                          "macro %qs defined multiple times",
     250            0 :                          macro.get_rule_name ().as_string ().c_str ());
     251            0 :         }
     252         1275 :     }
     253              : 
     254        30559 :   if (macro.get_kind () == AST::MacroRulesDefinition::MacroKind::DeclMacro)
     255          837 :     insert_or_error_out (macro.get_rule_name (), macro, Namespace::Macros);
     256              : 
     257        30559 :   auto &mappings = Analysis::Mappings::get ();
     258        30559 :   if (mappings.lookup_macro_def (macro.get_node_id ()))
     259              :     return;
     260              : 
     261         1703 :   mappings.insert_macro_def (&macro);
     262              : }
     263              : 
     264              : void
     265       490593 : TopLevel::visit (AST::Function &function)
     266              : {
     267       490593 :   insert_or_error_out (function.get_function_name (), function,
     268              :                        Namespace::Values);
     269              : 
     270       490593 :   Analysis::Mappings::get ().add_function_node (function.get_node_id ());
     271              : 
     272       490593 :   DefaultResolver::visit (function);
     273       490593 : }
     274              : 
     275              : void
     276         1464 : TopLevel::visit (AST::StaticItem &static_item)
     277              : {
     278         1464 :   insert_or_error_out (static_item.get_identifier (), static_item,
     279              :                        Namespace::Values);
     280              : 
     281         1464 :   DefaultResolver::visit (static_item);
     282         1464 : }
     283              : 
     284              : void
     285            3 : TopLevel::visit (AST::ExternalStaticItem &static_item)
     286              : {
     287            9 :   insert_or_error_out (static_item.get_identifier ().as_string (), static_item,
     288              :                        Namespace::Values);
     289              : 
     290            3 :   DefaultResolver::visit (static_item);
     291            3 : }
     292              : 
     293              : void
     294        26137 : TopLevel::visit (AST::StructStruct &struct_item)
     295              : {
     296        26137 :   DefaultResolver::visit (struct_item);
     297              : 
     298        26137 :   insert_or_error_out (struct_item.get_struct_name (), struct_item,
     299              :                        Namespace::Types);
     300              : 
     301              :   // Do we need to insert the constructor in the value namespace as well?
     302              : 
     303              :   // Do we need to do anything if the struct is a unit struct?
     304        26137 :   if (struct_item.is_unit_struct ())
     305        15041 :     insert_or_error_out (struct_item.get_struct_name (), struct_item,
     306              :                          Namespace::Values);
     307        26137 : }
     308              : 
     309              : void
     310       293696 : TopLevel::visit (AST::TypeParam &type_param)
     311              : {
     312       293696 :   insert_or_error_out (type_param.get_type_representation (), type_param,
     313              :                        Namespace::Types);
     314              : 
     315       293696 :   DefaultResolver::visit (type_param);
     316       293696 : }
     317              : 
     318              : void
     319         3020 : TopLevel::visit (AST::ConstGenericParam &const_param)
     320              : {
     321         3020 :   insert_or_error_out (const_param.get_name (), const_param, Namespace::Values);
     322              : 
     323         3020 :   DefaultResolver::visit (const_param);
     324         3020 : }
     325              : 
     326              : void
     327         6722 : TopLevel::visit (AST::TupleStruct &tuple_struct)
     328              : {
     329         6722 :   insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
     330              :                        Namespace::Types);
     331              : 
     332         6722 :   insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
     333              :                        Namespace::Values);
     334              : 
     335         6722 :   DefaultResolver::visit (tuple_struct);
     336         6722 : }
     337              : 
     338              : void
     339         3687 : TopLevel::visit (AST::EnumItem &variant)
     340              : {
     341         3687 :   insert_enum_variant_or_error_out (variant.get_identifier (), variant, true);
     342              : 
     343         3687 :   DefaultResolver::visit (variant);
     344         3687 : }
     345              : 
     346              : void
     347         2543 : TopLevel::visit (AST::EnumItemTuple &variant)
     348              : {
     349         2543 :   insert_enum_variant_or_error_out (variant.get_identifier (), variant, true);
     350              : 
     351         2543 :   DefaultResolver::visit (variant);
     352         2543 : }
     353              : 
     354              : void
     355          303 : TopLevel::visit (AST::EnumItemStruct &variant)
     356              : {
     357          303 :   insert_enum_variant_or_error_out (variant.get_identifier (), variant, false);
     358              : 
     359          303 :   DefaultResolver::visit (variant);
     360          303 : }
     361              : 
     362              : void
     363         1088 : TopLevel::visit (AST::EnumItemDiscriminant &variant)
     364              : {
     365         1088 :   insert_enum_variant_or_error_out (variant.get_identifier (), variant, true);
     366              : 
     367         1088 :   DefaultResolver::visit (variant);
     368         1088 : }
     369              : 
     370              : void
     371         2997 : TopLevel::visit (AST::Enum &enum_item)
     372              : {
     373         2997 :   insert_or_error_out (enum_item.get_identifier (), enum_item,
     374              :                        Namespace::Types);
     375              : 
     376         2997 :   DefaultResolver::visit (enum_item);
     377              : 
     378              :   // Since enums can be containers for imports, we need to insert them like we
     379              :   // do for modules
     380         5994 :   if (Analysis::Mappings::get ().lookup_glob_container (
     381         2997 :         enum_item.get_node_id ())
     382         2997 :       == tl::nullopt)
     383          601 :     Analysis::Mappings::get ().insert_glob_container (enum_item.get_node_id (),
     384              :                                                       &enum_item);
     385         2997 : }
     386              : 
     387              : void
     388          411 : TopLevel::visit (AST::Union &union_item)
     389              : {
     390          411 :   insert_or_error_out (union_item.get_identifier (), union_item,
     391              :                        Namespace::Types);
     392              : 
     393          411 :   DefaultResolver::visit (union_item);
     394          411 : }
     395              : 
     396              : void
     397        26953 : TopLevel::visit (AST::ConstantItem &const_item)
     398              : {
     399        26953 :   if (const_item.get_identifier ().as_string () != Values::Keywords::UNDERSCORE)
     400        26935 :     insert_or_error_out (const_item.get_identifier (), const_item,
     401              :                          Namespace::Values);
     402              : 
     403        26953 :   DefaultResolver::visit (const_item);
     404        26953 : }
     405              : 
     406              : void
     407        93474 : TopLevel::visit (AST::TypeAlias &type_item)
     408              : {
     409        93474 :   insert_or_error_out (type_item.get_new_type_name (), type_item,
     410              :                        Namespace::Types);
     411              : 
     412        93474 :   DefaultResolver::visit (type_item);
     413        93474 : }
     414              : 
     415              : void
     416           42 : TopLevel::visit (AST::ExternalTypeItem &type_item)
     417              : {
     418           42 :   insert_or_error_out (type_item.get_identifier (), type_item,
     419              :                        Namespace::Types);
     420              : 
     421           42 :   DefaultResolver::visit (type_item);
     422           42 : }
     423              : 
     424              : static void flatten_rebind (
     425              :   const AST::UseTreeRebind &glob,
     426              :   std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths);
     427              : 
     428              : static void flatten_list (
     429              :   const AST::UseTreeList &glob, std::vector<AST::SimplePath> &paths,
     430              :   std::vector<AST::SimplePath> &glob_paths,
     431              :   std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths,
     432              :   NameResolutionContext &ctx);
     433              : static void flatten_glob (const AST::UseTreeGlob &glob,
     434              :                           std::vector<AST::SimplePath> &glob_paths,
     435              :                           NameResolutionContext &ctx);
     436              : 
     437              : static void
     438        54685 : flatten (
     439              :   const AST::UseTree *tree, std::vector<AST::SimplePath> &paths,
     440              :   std::vector<AST::SimplePath> &glob_paths,
     441              :   std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths,
     442              :   NameResolutionContext &ctx)
     443              : {
     444        54685 :   switch (tree->get_kind ())
     445              :     {
     446        41964 :     case AST::UseTree::Rebind:
     447        41964 :       {
     448        41964 :         auto rebind = static_cast<const AST::UseTreeRebind *> (tree);
     449        41964 :         flatten_rebind (*rebind, rebind_paths);
     450        41964 :         break;
     451              :       }
     452         8767 :     case AST::UseTree::List:
     453         8767 :       {
     454         8767 :         auto list = static_cast<const AST::UseTreeList *> (tree);
     455         8767 :         flatten_list (*list, paths, glob_paths, rebind_paths, ctx);
     456         8767 :         break;
     457              :       }
     458         3954 :     case AST::UseTree::Glob:
     459         3954 :       {
     460         3954 :         auto glob = static_cast<const AST::UseTreeGlob *> (tree);
     461         3954 :         flatten_glob (*glob, glob_paths, ctx);
     462         3954 :         break;
     463              :       }
     464              :     }
     465        54685 : }
     466              : 
     467              : static void
     468        41964 : flatten_rebind (
     469              :   const AST::UseTreeRebind &rebind,
     470              :   std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths)
     471              : {
     472        41964 :   rebind_paths.emplace_back (rebind.get_path (), rebind);
     473        41964 : }
     474              : 
     475              : /** Prefix a list of subpath
     476              :  * @param prefix A prefix for all subpath
     477              :  * @param subs List of subpath to prefix
     478              :  * @param size List where results should be stored
     479              :  */
     480              : static void
     481        55530 : prefix_subpaths (AST::SimplePath prefix, std::vector<AST::SimplePath> subs,
     482              :                  std::vector<AST::SimplePath> &results)
     483              : {
     484        58530 :   for (auto &sub : subs)
     485              :     {
     486         3000 :       auto new_path = prefix;
     487         3000 :       std::copy (sub.get_segments ().begin (), sub.get_segments ().end (),
     488              :                  std::back_inserter (new_path.get_segments ()));
     489         3000 :       results.emplace_back (new_path);
     490         3000 :     }
     491        55530 : }
     492              : 
     493              : static void
     494        27765 : prefix_rebinds (
     495              :   AST::SimplePath prefix,
     496              :   std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> subs,
     497              :   std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &results)
     498              : {
     499        53862 :   for (auto &sub : subs)
     500              :     {
     501        26097 :       auto new_path = prefix;
     502        26097 :       std::copy (sub.first.get_segments ().begin (),
     503        26097 :                  sub.first.get_segments ().end (),
     504              :                  std::back_inserter (new_path.get_segments ()));
     505        52194 :       results.emplace_back (std::make_pair (new_path, sub.second));
     506        26097 :     }
     507        27765 : }
     508              : 
     509              : static void
     510         8767 : flatten_list (
     511              :   const AST::UseTreeList &list, std::vector<AST::SimplePath> &paths,
     512              :   std::vector<AST::SimplePath> &glob_paths,
     513              :   std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths,
     514              :   NameResolutionContext &ctx)
     515              : {
     516         8767 :   auto prefix = AST::SimplePath::create_empty ();
     517         8767 :   if (list.has_path ())
     518         8763 :     prefix = list.get_path ();
     519              : 
     520        36532 :   for (const auto &tree : list.get_trees ())
     521              :     {
     522        27765 :       auto sub_paths = std::vector<AST::SimplePath> ();
     523        27765 :       auto sub_globs = std::vector<AST::SimplePath> ();
     524        27765 :       auto sub_rebinds
     525              :         = std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> ();
     526        27765 :       flatten (tree.get (), sub_paths, sub_globs, sub_rebinds, ctx);
     527              : 
     528        27765 :       prefix_subpaths (prefix, sub_paths, paths);
     529        27765 :       prefix_subpaths (prefix, sub_globs, glob_paths);
     530        27765 :       prefix_rebinds (prefix, sub_rebinds, rebind_paths);
     531        27765 :     }
     532         8767 : }
     533              : 
     534              : static void
     535         3954 : flatten_glob (const AST::UseTreeGlob &glob, std::vector<AST::SimplePath> &paths,
     536              :               NameResolutionContext &ctx)
     537              : {
     538         3954 :   if (glob.has_path ())
     539         3945 :     paths.emplace_back (glob.get_path ());
     540              :   else
     541            9 :     paths.emplace_back (AST::SimplePath (
     542            9 :       {}, glob.get_glob_type () == AST::UseTreeGlob::PathType::GLOBAL,
     543           18 :       glob.get_locus ()));
     544         3954 : }
     545              : 
     546              : static bool
     547         3954 : has_prelude_import (const std::vector<AST::Attribute> &attributes)
     548              : {
     549         4101 :   for (const auto &attr : attributes)
     550          186 :     if (attr.get_path ().as_string () == "prelude_import")
     551         3954 :       return true;
     552              : 
     553              :   return false;
     554              : }
     555              : 
     556              : void
     557        26920 : TopLevel::visit (AST::UseDeclaration &use)
     558              : {
     559        26920 :   auto paths = std::vector<AST::SimplePath> ();
     560        26920 :   auto glob_path = std::vector<AST::SimplePath> ();
     561        26920 :   auto rebind_path
     562              :     = std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> ();
     563              : 
     564        26920 :   auto &values_rib = ctx.values.peek ();
     565        26920 :   auto &types_rib = ctx.types.peek ();
     566        26920 :   auto &macros_rib = ctx.macros.peek ();
     567              : 
     568              :   // FIXME: How do we handle `use foo::{self}` imports? Some beforehand cleanup?
     569              :   // How do we handle module imports in general? Should they get added to all
     570              :   // namespaces?
     571              : 
     572        26920 :   const auto &tree = use.get_tree ();
     573        26920 :   flatten (tree.get (), paths, glob_path, rebind_path, this->ctx);
     574              : 
     575        26920 :   auto imports = std::vector<ImportKind> ();
     576              : 
     577        26920 :   for (auto &&path : paths)
     578            0 :     imports.emplace_back (
     579            0 :       ImportKind::Simple (std::move (path), values_rib, types_rib, macros_rib));
     580              : 
     581        30874 :   for (auto &&glob : glob_path)
     582         7908 :     imports.emplace_back (
     583         3954 :       ImportKind::Glob (std::move (glob), values_rib, types_rib, macros_rib,
     584         3954 :                         has_prelude_import (use.get_outer_attrs ())));
     585              : 
     586        68884 :   for (auto &&rebind : rebind_path)
     587        41964 :     imports.emplace_back (
     588        83928 :       ImportKind::Rebind (std::move (rebind.first), std::move (rebind.second),
     589              :                           values_rib, types_rib, macros_rib));
     590              : 
     591        26920 :   imports_to_resolve.insert ({use.get_node_id (), std::move (imports)});
     592        26920 : }
     593              : 
     594              : } // namespace Resolver2_0
     595              : } // 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.