LCOV - code coverage report
Current view: top level - gcc/rust/resolve - rust-default-resolver.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 259 259
Test Date: 2026-07-11 15:47:05 Functions: 100.0 % 54 54
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-default-resolver.h"
      20              : #include "optional.h"
      21              : #include "rust-ast-full.h"
      22              : #include "rust-ast-visitor.h"
      23              : #include "rust-ast.h"
      24              : #include "rust-attribute-values.h"
      25              : #include "rust-item.h"
      26              : #include "rust-path.h"
      27              : 
      28              : namespace Rust {
      29              : namespace Resolver2_0 {
      30              : 
      31              : void
      32        31502 : DefaultResolver::visit (AST::Crate &crate)
      33              : {
      34              :   // Guard against infinite recursion: `extern crate self;` resolves to the
      35              :   // current crate, causing visit(AST::Crate) to call itself infinitely.
      36        31502 :   if (!visited_crates.insert (crate.get_node_id ()).second)
      37            6 :     return;
      38              : 
      39        31496 :   auto inner_fn = [this, &crate] () { AST::DefaultASTVisitor::visit (crate); };
      40              : 
      41        31496 :   auto &mappings = Analysis::Mappings::get ();
      42              : 
      43        31496 :   auto crate_num = mappings.lookup_crate_num (crate.get_node_id ());
      44        31496 :   rust_assert (crate_num.has_value ());
      45        31496 :   auto crate_name = mappings.get_crate_name (*crate_num);
      46        31496 :   rust_assert (crate_name.has_value ());
      47              : 
      48        62992 :   ctx.canonical_ctx.scope_crate (crate.get_node_id (), *crate_name, inner_fn);
      49              : }
      50              : 
      51              : void
      52       158013 : DefaultResolver::visit (AST::BlockExpr &expr)
      53              : {
      54              :   // extracting the lambda from the `scoped` call otherwise the code looks like
      55              :   // a hot turd thanks to our .clang-format
      56              : 
      57       158013 :   auto inner_fn = [this, &expr] () { AST::DefaultASTVisitor::visit (expr); };
      58              : 
      59       158013 :   ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), inner_fn);
      60       158008 : }
      61              : 
      62              : void
      63         9168 : DefaultResolver::visit (AST::Module &module)
      64              : {
      65         9168 :   auto item_fn_1
      66         9168 :     = [this, &module] () { AST::DefaultASTVisitor::visit (module); };
      67              : 
      68        18336 :   auto item_fn_2 = [this, &module, &item_fn_1] () {
      69         9168 :     ctx.canonical_ctx.scope (module.get_node_id (), module.get_name (),
      70              :                              std::move (item_fn_1));
      71        18336 :   };
      72              : 
      73        18336 :   ctx.scoped (Rib::Kind::Module, module.get_node_id (), item_fn_2,
      74        18336 :               module.get_name ());
      75         9168 : }
      76              : 
      77              : void
      78       128633 : DefaultResolver::visit (AST::Function &function)
      79              : {
      80       128633 :   auto def_fn_1
      81       128633 :     = [this, &function] () { AST::DefaultASTVisitor::visit (function); };
      82              : 
      83       257266 :   auto def_fn_2 = [this, &function, &def_fn_1] () {
      84       128633 :     ctx.canonical_ctx.scope (function.get_node_id (),
      85       128633 :                              function.get_function_name (),
      86              :                              std::move (def_fn_1));
      87       257264 :   };
      88              : 
      89       257266 :   ctx.scoped (Rib::Kind::Function, function.get_node_id (), def_fn_2,
      90       257264 :               function.get_function_name ());
      91       128631 : }
      92              : 
      93              : void
      94          132 : DefaultResolver::visit (AST::ForLoopExpr &expr)
      95              : {
      96          132 :   ctx.scoped (Rib::Kind::Normal, expr.get_node_id (),
      97          396 :               [this, &expr] () { AST::DefaultASTVisitor::visit (expr); });
      98          132 : }
      99              : 
     100              : void
     101          180 : DefaultResolver::visit_if_let_patterns (AST::IfLetExpr &expr)
     102              : {
     103          180 :   visit (expr.get_pattern ());
     104          180 : }
     105              : 
     106              : void
     107          180 : DefaultResolver::visit (AST::IfLetExpr &expr)
     108              : {
     109          360 :   auto inner_vis = [this, &expr] () {
     110          180 :     visit_if_let_patterns (expr);
     111          180 :     visit (expr.get_if_block ());
     112          360 :   };
     113              : 
     114          180 :   visit_outer_attrs (expr);
     115              : 
     116          180 :   visit (expr.get_value_expr ());
     117              : 
     118          180 :   ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), inner_vis);
     119          180 : }
     120              : 
     121              : void
     122           72 : DefaultResolver::visit (AST::IfLetExprConseqElse &expr)
     123              : {
     124           72 :   DefaultResolver::visit (static_cast<AST::IfLetExpr &> (expr));
     125           72 :   visit (expr.get_else_block ());
     126           72 : }
     127              : 
     128              : void
     129        26377 : DefaultResolver::visit (AST::Trait &trait)
     130              : {
     131        26377 :   visit_outer_attrs (trait);
     132        26377 :   visit (trait.get_visibility ());
     133        26377 :   visit_inner_attrs (trait);
     134              : 
     135        52754 :   auto inner_fn_1 = [this, &trait] () {
     136        50357 :     for (auto &item : trait.get_trait_items ())
     137        23980 :       visit (item);
     138        52754 :   };
     139              : 
     140        52754 :   auto inner_fn_2 = [this, &trait, &inner_fn_1] () {
     141        26377 :     visit (trait.get_implicit_self ());
     142        30999 :     for (auto &generic : trait.get_generic_params ())
     143         4622 :       visit (generic);
     144        26377 :     if (trait.has_where_clause ())
     145           56 :       visit (trait.get_where_clause ());
     146        30979 :     for (auto &bound : trait.get_type_param_bounds ())
     147         4602 :       visit (bound);
     148              : 
     149        26377 :     ctx.scoped (Rib::Kind::TraitOrImpl, trait.get_node_id (), inner_fn_1);
     150        52754 :   };
     151              : 
     152        52754 :   auto inner_fn_3 = [this, &trait, &inner_fn_2] () {
     153        26377 :     ctx.canonical_ctx.scope (trait.get_node_id (), trait.get_identifier (),
     154              :                              std::move (inner_fn_2));
     155        52754 :   };
     156              : 
     157        52754 :   ctx.scoped (Rib::Kind::Generics, trait.get_node_id (), inner_fn_3,
     158        52754 :               trait.get_identifier () /* FIXME: Is that valid?*/);
     159        26377 : }
     160              : 
     161              : static bool
     162         6488 : is_lang_impl (std::vector<AST::Attribute> &outer_attrs)
     163              : {
     164         6497 :   for (auto &attr : outer_attrs)
     165         1357 :     if (attr.get_path ().as_string () == Values::Attributes::LANG)
     166         6488 :       return true;
     167              : 
     168              :   return false;
     169              : }
     170              : 
     171              : void
     172         6488 : DefaultResolver::visit (AST::InherentImpl &impl)
     173              : {
     174         6488 :   visit_outer_attrs (impl);
     175         6488 :   visit (impl.get_visibility ());
     176         6488 :   visit_inner_attrs (impl);
     177              : 
     178        12976 :   auto inner_fn_1 = [this, &impl] () {
     179        26052 :     for (auto &item : impl.get_impl_items ())
     180        19564 :       visit (item);
     181        12976 :   };
     182              : 
     183        12976 :   auto inner_fn_2 = [this, &impl, &inner_fn_1] () {
     184         6488 :     maybe_insert_big_self (impl);
     185         8737 :     for (auto &generic : impl.get_generic_params ())
     186         2249 :       visit (generic);
     187         6488 :     if (impl.has_where_clause ())
     188            5 :       visit (impl.get_where_clause ());
     189         6488 :     visit_impl_type (impl.get_type ());
     190              : 
     191         6488 :     ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn_1);
     192        12976 :   };
     193              : 
     194        12976 :   auto inner_fn_3 = [this, &impl, &inner_fn_2] () {
     195         6488 :     ctx.canonical_ctx.scope_impl (impl, std::move (inner_fn_2));
     196        12976 :   };
     197              : 
     198         6488 :   ctx.scoped (Rib::Kind::Generics, impl.get_node_id (), inner_fn_3);
     199              : 
     200         6488 :   if (is_lang_impl (impl.get_outer_attrs ()))
     201              :     {
     202         1348 :       if (impl.get_type ().get_type_kind () == AST::Type::Kind::TypePath)
     203              :         {
     204          258 :           auto type = static_cast<AST::TypePath &> (impl.get_type ());
     205          258 :           auto type_name = type.as_string ();
     206              : 
     207          774 :           ctx.types.insert_lang_prelude (type_name, impl.get_node_id ());
     208          258 :         }
     209              :     }
     210         6488 : }
     211              : 
     212              : void
     213        32139 : DefaultResolver::visit (AST::TraitImpl &impl)
     214              : {
     215        32139 :   visit_outer_attrs (impl);
     216        32139 :   visit (impl.get_visibility ());
     217        32139 :   visit_inner_attrs (impl);
     218              : 
     219        64278 :   auto inner_fn_1 = [this, &impl] () {
     220        69908 :     for (auto &item : impl.get_impl_items ())
     221        37769 :       visit (item);
     222        64278 :   };
     223              : 
     224        64278 :   auto inner_fn_2 = [this, &impl, &inner_fn_1] () {
     225        32139 :     maybe_insert_big_self (impl);
     226        37545 :     for (auto &generic : impl.get_generic_params ())
     227         5406 :       visit (generic);
     228        32139 :     if (impl.has_where_clause ())
     229          600 :       visit (impl.get_where_clause ());
     230        32139 :     visit_impl_type (impl.get_type ());
     231        32139 :     visit (impl.get_trait_path ());
     232              : 
     233        32139 :     ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn_1);
     234        64278 :   };
     235              : 
     236        64278 :   auto inner_fn_3 = [this, &impl, &inner_fn_2] () {
     237        32139 :     ctx.canonical_ctx.scope_impl (impl, std::move (inner_fn_2));
     238        64278 :   };
     239              : 
     240        32139 :   ctx.scoped (Rib::Kind::Generics, impl.get_node_id (), inner_fn_3);
     241        32139 : }
     242              : 
     243              : void
     244        10644 : DefaultResolver::visit (AST::StructStruct &type)
     245              : {
     246        10644 :   auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
     247              : 
     248        21288 :   auto inner_fn_2 = [this, &type, &inner_fn_1] () {
     249        10644 :     ctx.canonical_ctx.scope (type.get_node_id (), type.get_struct_name (),
     250              :                              std::move (inner_fn_1));
     251        21288 :   };
     252              : 
     253        10644 :   ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
     254        31932 :               inner_fn_2, type.get_struct_name ());
     255        10644 : }
     256              : 
     257              : void
     258         6139 : DefaultResolver::visit (AST::TupleStruct &type)
     259              : {
     260         6139 :   auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
     261              : 
     262        12278 :   auto inner_fn_2 = [this, &type, &inner_fn_1] () {
     263         6139 :     ctx.canonical_ctx.scope (type.get_node_id (), type.get_struct_name (),
     264              :                              std::move (inner_fn_1));
     265        12278 :   };
     266              : 
     267         6139 :   ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
     268        18417 :               inner_fn_2, type.get_struct_name ());
     269         6139 : }
     270              : 
     271              : void
     272         3042 : DefaultResolver::visit (AST::EnumItem &item)
     273              : {
     274         3042 :   auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
     275              : 
     276         3042 :   ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
     277              :                            inner_fn);
     278         3042 : }
     279              : 
     280              : void
     281         3123 : DefaultResolver::visit (AST::EnumItemTuple &item)
     282              : {
     283         3123 :   auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
     284              : 
     285         3123 :   ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
     286              :                            inner_fn);
     287         3123 : }
     288              : 
     289              : void
     290          610 : DefaultResolver::visit (AST::EnumItemStruct &item)
     291              : {
     292          610 :   auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
     293              : 
     294          610 :   ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
     295              :                            inner_fn);
     296          610 : }
     297              : 
     298              : void
     299         1947 : DefaultResolver::visit (AST::EnumItemDiscriminant &item)
     300              : {
     301         1947 :   auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
     302              : 
     303         1947 :   ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
     304              :                            inner_fn);
     305         1947 : }
     306              : 
     307              : void
     308         3763 : DefaultResolver::visit (AST::Enum &type)
     309              : {
     310         3763 :   auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
     311              : 
     312         7526 :   auto inner_fn_2 = [this, &type, &inner_fn_1] () {
     313         3763 :     ctx.canonical_ctx.scope (type.get_node_id (), type.get_identifier (),
     314              :                              std::move (inner_fn_1));
     315         7526 :   };
     316              : 
     317         7526 :   ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
     318        11289 :               inner_fn_2, type.get_identifier ());
     319         3763 : }
     320              : 
     321              : void
     322          675 : DefaultResolver::visit (AST::Union &type)
     323              : {
     324          675 :   auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
     325              : 
     326         1350 :   auto inner_fn_2 = [this, &type, &inner_fn_1] () {
     327          675 :     ctx.canonical_ctx.scope (type.get_node_id (), type.get_identifier (),
     328              :                              std::move (inner_fn_1));
     329         1350 :   };
     330              : 
     331         1350 :   ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
     332         2025 :               inner_fn_2, type.get_identifier ());
     333          675 : }
     334              : 
     335              : void
     336         9040 : DefaultResolver::visit (AST::TypeAlias &type)
     337              : {
     338         9040 :   auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
     339              : 
     340        18080 :   auto inner_fn_2 = [this, &type, &inner_fn_1] () {
     341         9040 :     ctx.canonical_ctx.scope (type.get_node_id (), type.get_new_type_name (),
     342              :                              std::move (inner_fn_1));
     343        18080 :   };
     344              : 
     345        18080 :   ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
     346        27120 :               inner_fn_2, type.get_new_type_name ());
     347         9040 : }
     348              : 
     349              : void
     350          402 : DefaultResolver::visit_closure_params (AST::ClosureExpr &expr)
     351              : {
     352          780 :   for (auto &param : expr.get_params ())
     353          378 :     visit (param);
     354          402 : }
     355              : 
     356              : void
     357          402 : DefaultResolver::visit (AST::ClosureExpr &expr)
     358              : {
     359          804 :   auto expr_fn = [this, &expr] () {
     360          402 :     visit_closure_params (expr);
     361          402 :     visit (expr.get_definition_expr ());
     362          804 :   };
     363              : 
     364          402 :   visit_outer_attrs (expr);
     365              : 
     366          402 :   ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), expr_fn);
     367          402 : }
     368              : 
     369              : void
     370          222 : DefaultResolver::visit (AST::ClosureExprInner &expr)
     371              : {
     372          222 :   if (expr.is_marked_for_strip ())
     373              :     return;
     374              : 
     375          222 :   visit (static_cast<AST::ClosureExpr &> (expr));
     376              : }
     377              : 
     378              : void
     379          180 : DefaultResolver::visit (AST::ClosureExprInnerTyped &expr)
     380              : {
     381          180 :   if (expr.is_marked_for_strip ())
     382              :     return;
     383              : 
     384          180 :   visit (static_cast<AST::ClosureExpr &> (expr));
     385          180 :   visit (expr.get_return_type ());
     386              : }
     387              : 
     388              : void
     389         7018 : DefaultResolver::visit (AST::MatchExpr &expr)
     390              : {
     391         7018 :   if (expr.is_marked_for_strip ())
     392              :     return;
     393              : 
     394         7018 :   AST::DefaultASTVisitor::visit (expr);
     395              : }
     396              : 
     397              : void
     398        16294 : DefaultResolver::visit (AST::MatchCase &cas)
     399              : {
     400        16294 :   auto vis = [this, &cas] () { AST::DefaultASTVisitor::visit (cas); };
     401              : 
     402        16294 :   ctx.scoped (Rib::Kind::Normal, cas.get_node_id (), vis);
     403        16293 : }
     404              : 
     405              : void
     406         3556 : DefaultResolver::visit (AST::ConstantItem &item)
     407              : {
     408         3556 :   auto expr_vis_1 = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
     409              : 
     410         7112 :   auto expr_vis_2 = [this, &item, &expr_vis_1] () {
     411         3556 :     ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
     412              :                              std::move (expr_vis_1));
     413         7112 :   };
     414              : 
     415              :   // FIXME: Why do we need a Rib here?
     416         3556 :   ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis_2);
     417         3556 : }
     418              : 
     419              : void
     420          371 : DefaultResolver::visit (AST::StaticItem &item)
     421              : {
     422          371 :   auto expr_vis_1 = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
     423              : 
     424          742 :   auto expr_vis_2 = [this, &item, &expr_vis_1] () {
     425          371 :     ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
     426              :                              std::move (expr_vis_1));
     427          742 :   };
     428              : 
     429              :   // FIXME: Why do we need a Rib here?
     430          371 :   ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis_2);
     431          371 : }
     432              : 
     433              : void
     434        58215 : DefaultResolver::visit (AST::TypeParam &param)
     435              : {
     436        58215 :   auto expr_vis = [this, &param] () { AST::DefaultASTVisitor::visit (param); };
     437              : 
     438        58215 :   ctx.scoped (Rib::Kind::ForwardTypeParamBan, param.get_node_id (), expr_vis);
     439        58215 : }
     440              : 
     441              : void
     442           75 : DefaultResolver::visit_extern_crate (AST::ExternCrate &extern_crate,
     443              :                                      AST::Crate &crate, CrateNum num)
     444              : {
     445           75 :   visit (crate);
     446           75 : }
     447              : 
     448              : void
     449          159 : DefaultResolver::visit (AST::ExternCrate &crate)
     450              : {
     451          159 :   auto &mappings = Analysis::Mappings::get ();
     452          159 :   tl::optional<CrateNum> num_opt;
     453          159 :   if (crate.get_referenced_crate () == "self")
     454            6 :     num_opt = mappings.get_current_crate ();
     455              :   else
     456          153 :     num_opt = mappings.lookup_crate_name (crate.get_referenced_crate ());
     457              : 
     458          159 :   if (!num_opt)
     459              :     {
     460            9 :       rust_error_at (crate.get_locus (), "unknown crate %qs",
     461            9 :                      crate.get_referenced_crate ().c_str ());
     462            9 :       return;
     463              :     }
     464              : 
     465          150 :   CrateNum num = *num_opt;
     466              : 
     467          150 :   AST::Crate &referenced_crate = mappings.get_ast_crate (num);
     468              : 
     469          150 :   auto sub_visitor_1
     470          150 :     = [&, this] () { visit_extern_crate (crate, referenced_crate, num); };
     471              : 
     472          300 :   auto sub_visitor_2 = [&] () {
     473          150 :     ctx.canonical_ctx.scope_crate (referenced_crate.get_node_id (),
     474          150 :                                    crate.get_referenced_crate () == "self"
     475            6 :                                      ? mappings.get_current_crate_name ()
     476              :                                      : crate.get_referenced_crate (),
     477              :                                    std::move (sub_visitor_1));
     478          300 :   };
     479              : 
     480          150 :   if (crate.has_as_clause ())
     481           12 :     ctx.scoped (Rib::Kind::Module, referenced_crate.get_node_id (),
     482           18 :                 sub_visitor_2, crate.get_as_clause ());
     483              :   else
     484          144 :     ctx.scoped (Rib::Kind::Module, referenced_crate.get_node_id (),
     485          432 :                 sub_visitor_2, crate.get_referenced_crate ());
     486              : }
     487              : 
     488              : } // namespace Resolver2_0
     489              : } // 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.