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