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