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