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.9 % 274 260
Test Date: 2026-10-24 16:24:59 Functions: 100.0 % 64 64
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        16571 : TopLevel::TopLevel (NameResolutionContext &resolver)
      30        16571 :   : DefaultResolver (resolver), dirty (false)
      31        16571 : {}
      32              : 
      33              : template <typename T>
      34              : void
      35         8234 : TopLevel::insert_enum_variant_or_error_out (const Identifier &identifier,
      36              :                                             const T &node, bool is_also_value)
      37              : {
      38         8234 :   insert_enum_variant_or_error_out (identifier, node.get_locus (),
      39         8234 :                                     node.get_node_id (), is_also_value);
      40         8234 : }
      41              : 
      42              : void
      43      1321711 : 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      1321711 :   if (result)
      48        94051 :     dirty = true;
      49      1227660 :   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      1321711 : }
      68              : void
      69         8234 : 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         8234 :   node_locations.emplace (node_id, locus);
      76              : 
      77         8234 :   auto result = ctx.insert_variant (identifier, node_id, is_also_value);
      78        14929 :   check_multiple_insertion_error (result, identifier, locus, node_id);
      79         8234 : }
      80              : 
      81              : template <typename T>
      82              : void
      83      1304508 : TopLevel::insert_or_error_out (const Identifier &identifier, const T &node,
      84              :                                Namespace ns)
      85              : {
      86      1304508 :   insert_or_error_out (identifier, node.get_locus (), node.get_node_id (), ns);
      87      1304508 : }
      88              : 
      89              : void
      90      1313477 : 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      1313477 :   node_locations.emplace (node_id, locus);
      96              : 
      97      1313477 :   auto result = ctx.insert (identifier, node_id, ns);
      98      2534442 :   check_multiple_insertion_error (result, identifier, locus, node_id);
      99      1313477 : }
     100              : 
     101              : void
     102        16571 : 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        16571 :   visit (crate);
     110              : 
     111        16571 :   if (Analysis::Mappings::get ().lookup_glob_container (crate.get_node_id ())
     112        16571 :       == tl::nullopt)
     113         5098 :     Analysis::Mappings::get ().insert_glob_container (crate.get_node_id (),
     114              :                                                       &crate);
     115        16571 : }
     116              : 
     117              : void
     118        13844 : TopLevel::visit (AST::Module &module)
     119              : {
     120        13844 :   if (Analysis::Mappings::get ().lookup_glob_container (module.get_node_id ())
     121        13844 :       == tl::nullopt)
     122         1732 :     Analysis::Mappings::get ().insert_glob_container (module.get_node_id (),
     123              :                                                       &module);
     124              : 
     125        13844 :   insert_or_error_out (module.get_name (), module, Namespace::Types);
     126              : 
     127        13844 :   Analysis::Mappings::get ().insert_module_id (module.get_node_id ());
     128              : 
     129        13844 :   DefaultResolver::visit (module);
     130        13844 : }
     131              : 
     132              : void
     133        19586 : TopLevel::visit (AST::Trait &trait)
     134              : {
     135        19586 :   insert_or_error_out (trait.get_identifier (), trait, Namespace::Types);
     136              : 
     137        19586 :   DefaultResolver::visit (trait);
     138        19586 : }
     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       266834 : TopLevel::maybe_insert_big_self (AST::Impl &impl)
     153              : {
     154       533668 :   insert_or_error_out (Identifier ("Self", impl.get_type ().get_locus ()),
     155       266834 :                        impl.get_type (), Namespace::Types);
     156       266834 : }
     157              : 
     158              : void
     159         4449 : TopLevel::visit (AST::TraitItemType &trait_item)
     160              : {
     161        13347 :   insert_or_error_out (trait_item.get_identifier ().as_string (), trait_item,
     162              :                        Namespace::Types);
     163              : 
     164         4449 :   DefaultResolver::visit (trait_item);
     165         4449 : }
     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.crate.attributes.lookup (num);
     191              : 
     192          171 :   auto bang_macros = mappings.crate.bangs.lookup (num);
     193              : 
     194          171 :   auto derive_macros = mappings.crate.derives.lookup (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.pmacro.definitions.derives.insert (macro.get_node_id (),
     202              :                                                     macro);
     203              :     }
     204          171 :   if (attribute_macros.has_value ())
     205              :     {
     206          168 :       insert_macros (attribute_macros.value (), ctx);
     207          168 :       for (auto &macro : attribute_macros.value ())
     208            0 :         mappings.pmacro.definitions.attributes.insert (macro.get_node_id (),
     209              :                                                        macro);
     210              :     }
     211          171 :   if (bang_macros.has_value ())
     212              :     {
     213          168 :       insert_macros (bang_macros.value (), ctx);
     214          168 :       for (auto &macro : bang_macros.value ())
     215            0 :         mappings.pmacro.definitions.bangs.insert (macro.get_node_id (), macro);
     216              :     }
     217              : 
     218              :   // We do *NOT* visit the crate because loaded crates are resolved
     219              :   // independently.
     220          171 : }
     221              : 
     222              : static bool
     223        31105 : is_macro_export (AST::MacroRulesDefinition &def)
     224              : {
     225        74989 :   for (const auto &attr : def.get_outer_attrs ())
     226        45222 :     if (attr.get_path ().as_string () == Values::Attributes::MACRO_EXPORT)
     227        31105 :       return true;
     228              : 
     229              :   return false;
     230              : }
     231              : 
     232              : void
     233        31105 : TopLevel::visit (AST::MacroRulesDefinition &macro)
     234              : {
     235              :   // we do not insert macros in the current rib as that needs to be done in the
     236              :   // textual scope of the Early pass. we only insert them in the root of the
     237              :   // crate if they are marked with #[macro_export]. The execption to this is
     238              :   // macros 2.0, which get resolved and inserted like regular items.
     239              : 
     240        31105 :   if (is_macro_export (macro))
     241              :     {
     242         4014 :       auto res = ctx.macros.insert_at_root (macro.get_rule_name (),
     243         1338 :                                             macro.get_node_id ());
     244         1338 :       if (!res && res.error ().existing != macro.get_node_id ())
     245              :         {
     246              :           // TODO: Factor this
     247            0 :           rich_location rich_loc (line_table, macro.get_locus ());
     248            0 :           rich_loc.add_range (node_locations[res.error ().existing]);
     249              : 
     250            0 :           rust_error_at (rich_loc, ErrorCode::E0428,
     251              :                          "macro %qs defined multiple times",
     252            0 :                          macro.get_rule_name ().as_string ().c_str ());
     253            0 :         }
     254         1338 :     }
     255              : 
     256        31105 :   if (macro.get_kind () == AST::MacroRulesDefinition::MacroKind::DeclMacro)
     257          882 :     insert_or_error_out (macro.get_rule_name (), macro, Namespace::Macros);
     258              : 
     259        31105 :   auto &mappings = Analysis::Mappings::get ();
     260        31105 :   if (mappings.lookup_macro_def (macro.get_node_id ()))
     261              :     return;
     262              : 
     263         1815 :   mappings.insert_macro_def (&macro);
     264              : }
     265              : 
     266              : void
     267       505760 : TopLevel::visit (AST::Function &function)
     268              : {
     269       505760 :   insert_or_error_out (function.get_function_name (), function,
     270              :                        Namespace::Values);
     271              : 
     272       505760 :   Analysis::Mappings::get ().add_function_node (function.get_node_id ());
     273              : 
     274       505760 :   DefaultResolver::visit (function);
     275       505760 : }
     276              : 
     277              : void
     278         1542 : TopLevel::visit (AST::StaticItem &static_item)
     279              : {
     280         1542 :   insert_or_error_out (static_item.get_identifier (), static_item,
     281              :                        Namespace::Values);
     282              : 
     283         1542 :   DefaultResolver::visit (static_item);
     284         1542 : }
     285              : 
     286              : void
     287            3 : TopLevel::visit (AST::ExternalStaticItem &static_item)
     288              : {
     289            9 :   insert_or_error_out (static_item.get_identifier ().as_string (), static_item,
     290              :                        Namespace::Values);
     291              : 
     292            3 :   DefaultResolver::visit (static_item);
     293            3 : }
     294              : 
     295              : void
     296        27443 : TopLevel::visit (AST::StructStruct &struct_item)
     297              : {
     298        27443 :   DefaultResolver::visit (struct_item);
     299              : 
     300        27443 :   insert_or_error_out (struct_item.get_struct_name (), struct_item,
     301              :                        Namespace::Types);
     302              : 
     303              :   // Do we need to insert the constructor in the value namespace as well?
     304              : 
     305              :   // Do we need to do anything if the struct is a unit struct?
     306        27443 :   if (struct_item.is_unit_struct ())
     307        15226 :     insert_or_error_out (struct_item.get_struct_name (), struct_item,
     308              :                          Namespace::Values);
     309        27443 : }
     310              : 
     311              : void
     312       305758 : TopLevel::visit (AST::TypeParam &type_param)
     313              : {
     314       305758 :   insert_or_error_out (type_param.get_type_representation (), type_param,
     315              :                        Namespace::Types);
     316              : 
     317       305758 :   DefaultResolver::visit (type_param);
     318       305758 : }
     319              : 
     320              : void
     321         3105 : TopLevel::visit (AST::ConstGenericParam &const_param)
     322              : {
     323         3105 :   insert_or_error_out (const_param.get_name (), const_param, Namespace::Values);
     324              : 
     325         3105 :   DefaultResolver::visit (const_param);
     326         3105 : }
     327              : 
     328              : void
     329         7020 : TopLevel::visit (AST::TupleStruct &tuple_struct)
     330              : {
     331         7020 :   insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
     332              :                        Namespace::Types);
     333              : 
     334         7020 :   insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
     335              :                        Namespace::Values);
     336              : 
     337         7020 :   DefaultResolver::visit (tuple_struct);
     338         7020 : }
     339              : 
     340              : void
     341         3890 : TopLevel::visit (AST::EnumItem &variant)
     342              : {
     343         3890 :   insert_enum_variant_or_error_out (variant.get_identifier (), variant, true);
     344              : 
     345         3890 :   DefaultResolver::visit (variant);
     346         3890 : }
     347              : 
     348              : void
     349         2901 : TopLevel::visit (AST::EnumItemTuple &variant)
     350              : {
     351         2901 :   insert_enum_variant_or_error_out (variant.get_identifier (), variant, true);
     352              : 
     353         2901 :   DefaultResolver::visit (variant);
     354         2901 : }
     355              : 
     356              : void
     357          328 : TopLevel::visit (AST::EnumItemStruct &variant)
     358              : {
     359          328 :   insert_enum_variant_or_error_out (variant.get_identifier (), variant, false);
     360              : 
     361          328 :   DefaultResolver::visit (variant);
     362          328 : }
     363              : 
     364              : void
     365         1115 : TopLevel::visit (AST::EnumItemDiscriminant &variant)
     366              : {
     367         1115 :   insert_enum_variant_or_error_out (variant.get_identifier (), variant, true);
     368              : 
     369         1115 :   DefaultResolver::visit (variant);
     370         1115 : }
     371              : 
     372              : void
     373         3285 : TopLevel::visit (AST::Enum &enum_item)
     374              : {
     375         3285 :   insert_or_error_out (enum_item.get_identifier (), enum_item,
     376              :                        Namespace::Types);
     377              : 
     378         3285 :   DefaultResolver::visit (enum_item);
     379              : 
     380              :   // Since enums can be containers for imports, we need to insert them like we
     381              :   // do for modules
     382         6570 :   if (Analysis::Mappings::get ().lookup_glob_container (
     383         3285 :         enum_item.get_node_id ())
     384         3285 :       == tl::nullopt)
     385          665 :     Analysis::Mappings::get ().insert_glob_container (enum_item.get_node_id (),
     386              :                                                       &enum_item);
     387         3285 : }
     388              : 
     389              : void
     390          421 : TopLevel::visit (AST::Union &union_item)
     391              : {
     392          421 :   insert_or_error_out (union_item.get_identifier (), union_item,
     393              :                        Namespace::Types);
     394              : 
     395          421 :   DefaultResolver::visit (union_item);
     396          421 : }
     397              : 
     398              : void
     399        27110 : TopLevel::visit (AST::ConstantItem &const_item)
     400              : {
     401        27110 :   if (const_item.get_identifier ().as_string () != Values::Keywords::UNDERSCORE)
     402        27089 :     insert_or_error_out (const_item.get_identifier (), const_item,
     403              :                          Namespace::Values);
     404              : 
     405        27110 :   DefaultResolver::visit (const_item);
     406        27110 : }
     407              : 
     408              : void
     409        95013 : TopLevel::visit (AST::TypeAlias &type_item)
     410              : {
     411        95013 :   insert_or_error_out (type_item.get_new_type_name (), type_item,
     412              :                        Namespace::Types);
     413              : 
     414        95013 :   DefaultResolver::visit (type_item);
     415        95013 : }
     416              : 
     417              : void
     418            6 : TopLevel::visit (AST::TraitAlias &trait_item)
     419              : {
     420            6 :   insert_or_error_out (trait_item.get_alias_name (), trait_item,
     421              :                        Namespace::Types);
     422              : 
     423            6 :   DefaultResolver::visit (trait_item);
     424            6 : }
     425              : 
     426              : void
     427           48 : TopLevel::visit (AST::ExternalTypeItem &type_item)
     428              : {
     429           48 :   insert_or_error_out (type_item.get_identifier (), type_item,
     430              :                        Namespace::Types);
     431              : 
     432           48 :   DefaultResolver::visit (type_item);
     433           48 : }
     434              : 
     435              : static void flatten_rebind (
     436              :   const AST::UseTreeRebind &glob,
     437              :   std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths);
     438              : 
     439              : static void flatten_list (
     440              :   const AST::UseTreeList &glob, std::vector<AST::SimplePath> &paths,
     441              :   std::vector<AST::SimplePath> &glob_paths,
     442              :   std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths,
     443              :   NameResolutionContext &ctx);
     444              : static void flatten_glob (const AST::UseTreeGlob &glob,
     445              :                           std::vector<AST::SimplePath> &glob_paths,
     446              :                           NameResolutionContext &ctx);
     447              : 
     448              : static void
     449        59807 : flatten (
     450              :   const AST::UseTree *tree, std::vector<AST::SimplePath> &paths,
     451              :   std::vector<AST::SimplePath> &glob_paths,
     452              :   std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths,
     453              :   NameResolutionContext &ctx)
     454              : {
     455        59807 :   switch (tree->get_kind ())
     456              :     {
     457        45944 :     case AST::UseTree::Rebind:
     458        45944 :       {
     459        45944 :         auto rebind = static_cast<const AST::UseTreeRebind *> (tree);
     460        45944 :         flatten_rebind (*rebind, rebind_paths);
     461        45944 :         break;
     462              :       }
     463         9651 :     case AST::UseTree::List:
     464         9651 :       {
     465         9651 :         auto list = static_cast<const AST::UseTreeList *> (tree);
     466         9651 :         flatten_list (*list, paths, glob_paths, rebind_paths, ctx);
     467         9651 :         break;
     468              :       }
     469         4212 :     case AST::UseTree::Glob:
     470         4212 :       {
     471         4212 :         auto glob = static_cast<const AST::UseTreeGlob *> (tree);
     472         4212 :         flatten_glob (*glob, glob_paths, ctx);
     473         4212 :         break;
     474              :       }
     475              :     }
     476        59807 : }
     477              : 
     478              : static void
     479        45944 : flatten_rebind (
     480              :   const AST::UseTreeRebind &rebind,
     481              :   std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths)
     482              : {
     483        45944 :   rebind_paths.emplace_back (rebind.get_path (), rebind);
     484        45944 : }
     485              : 
     486              : /** Prefix a list of subpath
     487              :  * @param prefix A prefix for all subpath
     488              :  * @param subs List of subpath to prefix
     489              :  * @param size List where results should be stored
     490              :  */
     491              : static void
     492        60772 : prefix_subpaths (AST::SimplePath prefix, std::vector<AST::SimplePath> subs,
     493              :                  std::vector<AST::SimplePath> &results)
     494              : {
     495        63817 :   for (auto &sub : subs)
     496              :     {
     497         3045 :       auto new_path = prefix;
     498         3045 :       std::copy (sub.get_segments ().begin (), sub.get_segments ().end (),
     499              :                  std::back_inserter (new_path.get_segments ()));
     500         3045 :       results.emplace_back (new_path);
     501         3045 :     }
     502        60772 : }
     503              : 
     504              : static void
     505        30386 : prefix_rebinds (
     506              :   AST::SimplePath prefix,
     507              :   std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> subs,
     508              :   std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &results)
     509              : {
     510        59059 :   for (auto &sub : subs)
     511              :     {
     512        28673 :       auto new_path = prefix;
     513        28673 :       std::copy (sub.first.get_segments ().begin (),
     514        28673 :                  sub.first.get_segments ().end (),
     515              :                  std::back_inserter (new_path.get_segments ()));
     516        57346 :       results.emplace_back (std::make_pair (new_path, sub.second));
     517        28673 :     }
     518        30386 : }
     519              : 
     520              : static void
     521         9651 : flatten_list (
     522              :   const AST::UseTreeList &list, std::vector<AST::SimplePath> &paths,
     523              :   std::vector<AST::SimplePath> &glob_paths,
     524              :   std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths,
     525              :   NameResolutionContext &ctx)
     526              : {
     527         9651 :   auto prefix = AST::SimplePath::create_empty ();
     528         9651 :   if (list.has_path ())
     529         9647 :     prefix = list.get_path ();
     530              : 
     531        40037 :   for (const auto &tree : list.get_trees ())
     532              :     {
     533        30386 :       auto sub_paths = std::vector<AST::SimplePath> ();
     534        30386 :       auto sub_globs = std::vector<AST::SimplePath> ();
     535        30386 :       auto sub_rebinds
     536              :         = std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> ();
     537        30386 :       flatten (tree.get (), sub_paths, sub_globs, sub_rebinds, ctx);
     538              : 
     539        30386 :       prefix_subpaths (prefix, sub_paths, paths);
     540        30386 :       prefix_subpaths (prefix, sub_globs, glob_paths);
     541        30386 :       prefix_rebinds (prefix, sub_rebinds, rebind_paths);
     542        30386 :     }
     543         9651 : }
     544              : 
     545              : static void
     546         4212 : flatten_glob (const AST::UseTreeGlob &glob, std::vector<AST::SimplePath> &paths,
     547              :               NameResolutionContext &ctx)
     548              : {
     549         4212 :   if (glob.has_path ())
     550         4198 :     paths.emplace_back (glob.get_path ());
     551              :   else
     552           14 :     paths.emplace_back (AST::SimplePath (
     553           14 :       {}, glob.get_glob_type () == AST::UseTreeGlob::PathType::GLOBAL,
     554           28 :       glob.get_locus ()));
     555         4212 : }
     556              : 
     557              : static bool
     558         4212 : has_prelude_import (const std::vector<AST::Attribute> &attributes)
     559              : {
     560         4379 :   for (const auto &attr : attributes)
     561          206 :     if (attr.get_path ().as_string () == "prelude_import")
     562         4212 :       return true;
     563              : 
     564              :   return false;
     565              : }
     566              : 
     567              : void
     568        29421 : TopLevel::visit (AST::UseDeclaration &use)
     569              : {
     570        29421 :   auto paths = std::vector<AST::SimplePath> ();
     571        29421 :   auto glob_path = std::vector<AST::SimplePath> ();
     572        29421 :   auto rebind_path
     573              :     = std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> ();
     574              : 
     575        29421 :   auto &values_rib = ctx.values.peek ();
     576        29421 :   auto &types_rib = ctx.types.peek ();
     577        29421 :   auto &macros_rib = ctx.macros.peek ();
     578              : 
     579              :   // FIXME: How do we handle `use foo::{self}` imports? Some beforehand cleanup?
     580              :   // How do we handle module imports in general? Should they get added to all
     581              :   // namespaces?
     582              : 
     583        29421 :   const auto &tree = use.get_tree ();
     584        29421 :   flatten (tree.get (), paths, glob_path, rebind_path, this->ctx);
     585              : 
     586        29421 :   auto imports = std::vector<ImportKind> ();
     587              : 
     588        29421 :   for (auto &&path : paths)
     589            0 :     imports.emplace_back (
     590            0 :       ImportKind::Simple (std::move (path), values_rib, types_rib, macros_rib));
     591              : 
     592        33633 :   for (auto &&glob : glob_path)
     593         8424 :     imports.emplace_back (
     594         4212 :       ImportKind::Glob (std::move (glob), values_rib, types_rib, macros_rib,
     595         4212 :                         has_prelude_import (use.get_outer_attrs ())));
     596              : 
     597        75365 :   for (auto &&rebind : rebind_path)
     598        45944 :     imports.emplace_back (
     599        91888 :       ImportKind::Rebind (std::move (rebind.first), std::move (rebind.second),
     600              :                           values_rib, types_rib, macros_rib));
     601              : 
     602        29421 :   imports_to_resolve.insert ({use.get_node_id (), std::move (imports)});
     603        29421 : }
     604              : 
     605              : } // namespace Resolver2_0
     606              : } // namespace Rust
        

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