LCOV - code coverage report
Current view: top level - gcc/rust/checks/errors/privacy - rust-visibility-resolver.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.1 % 118 104
Test Date: 2026-10-24 16:24:59 Functions: 89.5 % 19 17
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-visibility-resolver.h"
      20              : #include "rust-ast.h"
      21              : #include "rust-hir.h"
      22              : #include "rust-hir-item.h"
      23              : #include "rust-finalized-name-resolution-context.h"
      24              : #include "rust-rib.h"
      25              : 
      26              : namespace Rust {
      27              : namespace Privacy {
      28              : 
      29         4543 : VisibilityResolver::VisibilityResolver (
      30              :   Analysis::Mappings &mappings,
      31              :   const Resolver2_0::FinalizedNameResolutionContext &resolver)
      32         4543 :   : mappings (mappings), resolver (resolver)
      33         4543 : {}
      34              : 
      35              : void
      36         4543 : VisibilityResolver::go (HIR::Crate &crate)
      37              : {
      38         4543 :   mappings.ast.module_visibility.insert (crate.get_mappings ().get_nodeid (),
      39              :                                          ModuleVisibility::create_public ());
      40              : 
      41         4543 :   current_module = crate.get_mappings ().get_defid ();
      42              : 
      43        23964 :   for (auto &item : crate.get_items ())
      44              :     {
      45        19421 :       if (item->get_hir_kind () == HIR::Node::VIS_ITEM)
      46              :         {
      47        19421 :           auto vis_item = static_cast<HIR::VisItem *> (item.get ());
      48        19421 :           vis_item->accept_vis (*this);
      49              :         }
      50              :     }
      51         4543 : }
      52              : 
      53              : bool
      54           19 : VisibilityResolver::resolve_module_path (const HIR::SimplePath &restriction,
      55              :                                          DefId &id)
      56              : {
      57              :   // We need, from the restriction, to figure out the actual Module it
      58              :   // belongs to.
      59              : 
      60           19 :   NodeId ast_node_id = restriction.get_mappings ().get_nodeid ();
      61              : 
      62           19 :   auto invalid_path
      63              :     = Error (restriction.get_locus (),
      64           19 :              "cannot use non-module path as privacy restrictor");
      65              : 
      66           19 :   NodeId ref_node_id;
      67           19 :   if (auto id = resolver.lookup (ast_node_id, Resolver2_0::Namespace::Types))
      68              :     {
      69           19 :       ref_node_id = *id;
      70              :     }
      71              :   else
      72              :     {
      73            0 :       invalid_path.emit ();
      74            0 :       return false;
      75              :     }
      76              :   // FIXME: Add a hint here if we can find the path in another scope, such as
      77              :   // a type or something else
      78              :   // TODO: For the hint, can we point to the original item's definition if
      79              :   // present?
      80              : 
      81           19 :   tl::optional<HirId> hid = mappings.lookup_node_to_hir (ref_node_id);
      82           19 :   rust_assert (hid.has_value ());
      83           19 :   auto ref = hid.value ();
      84              : 
      85           19 :   auto crate
      86           19 :     = mappings.crate.get_ast_crate (mappings.crate.get_current_crate ());
      87              : 
      88              :   // we may be dealing with pub(crate)
      89           19 :   if (ref_node_id == crate.get_node_id ())
      90              :     // FIXME: What do we do here? There isn't a DefId for the Crate, so can we
      91              :     // actually do anything?
      92              :     // We basically want to return true always but just when exporting export
      93              :     // these items as private?
      94              :     return true;
      95              : 
      96            8 :   if (auto module = mappings.hir.modules.lookup (ref))
      97              :     {
      98              :       // Fill in the resolved `DefId`
      99            8 :       id = module.value ()->get_mappings ().get_defid ();
     100              : 
     101            8 :       return true;
     102              :     }
     103            0 :   invalid_path.emit ();
     104            0 :   return false;
     105           19 : }
     106              : 
     107              : bool
     108        23565 : VisibilityResolver::resolve_visibility (const HIR::Visibility &visibility,
     109              :                                         ModuleVisibility &to_resolve)
     110              : {
     111        23565 :   switch (visibility.get_vis_type ())
     112              :     {
     113        16082 :     case HIR::Visibility::VisType::Private:
     114        16082 :       to_resolve = ModuleVisibility::create_restricted (current_module);
     115        16082 :       return true;
     116         7464 :     case HIR::Visibility::VisType::Public:
     117         7464 :       to_resolve = ModuleVisibility::create_public ();
     118         7464 :       return true;
     119           19 :     case HIR::Visibility::VisType::Restricted:
     120           19 :       {
     121              :         // FIXME: We also need to handle 2015 vs 2018 edition conflicts
     122           19 :         auto id = UNKNOWN_DEFID;
     123           19 :         auto result = resolve_module_path (visibility.get_path (), id);
     124           19 :         to_resolve = ModuleVisibility::create_restricted (id);
     125           19 :         return result;
     126              :       }
     127            0 :     default:
     128            0 :       rust_unreachable ();
     129              :       return false;
     130              :     }
     131              : }
     132              : 
     133              : void
     134        18975 : VisibilityResolver::resolve_and_update (const HIR::VisItem *item)
     135              : {
     136        18975 :   ModuleVisibility module_vis;
     137        18975 :   if (!resolve_visibility (item->get_visibility (), module_vis))
     138              :     return; // we will already have emitted errors
     139              : 
     140        18975 :   mappings.ast.module_visibility.insert (item->get_mappings ().get_nodeid (),
     141              :                                          module_vis);
     142              : }
     143              : 
     144              : void
     145         1245 : VisibilityResolver::visit (HIR::Module &mod)
     146              : {
     147         1245 :   auto old_module = current_module;
     148         1245 :   current_module = mod.get_mappings ().get_defid ();
     149              : 
     150         5418 :   for (auto &item : mod.get_items ())
     151              :     {
     152         4173 :       if (item->get_hir_kind () == HIR::Node::VIS_ITEM)
     153              :         {
     154         4173 :           auto vis_item = static_cast<HIR::VisItem *> (item.get ());
     155         4173 :           vis_item->accept_vis (*this);
     156              :         }
     157              :     }
     158              : 
     159         1245 :   current_module = old_module;
     160         1245 : }
     161              : 
     162              : void
     163            0 : VisibilityResolver::visit (HIR::ExternCrate &)
     164            0 : {}
     165              : 
     166              : void
     167            0 : VisibilityResolver::visit (HIR::UseDeclaration &)
     168            0 : {}
     169              : 
     170              : void
     171        14579 : VisibilityResolver::visit (HIR::Function &func)
     172              : {
     173        14579 :   resolve_and_update (&func);
     174        14579 : }
     175              : 
     176              : void
     177         1483 : VisibilityResolver::visit (HIR::TypeAlias &type_alias)
     178              : {
     179         1483 :   resolve_and_update (&type_alias);
     180         1483 : }
     181              : 
     182              : void
     183         1511 : VisibilityResolver::visit (HIR::StructStruct &struct_item)
     184              : {
     185         1511 :   resolve_and_update (&struct_item);
     186         1511 : }
     187              : 
     188              : void
     189          834 : VisibilityResolver::visit (HIR::TupleStruct &tuple_struct)
     190              : {
     191          834 :   resolve_and_update (&tuple_struct);
     192          834 : }
     193              : 
     194              : void
     195          526 : VisibilityResolver::visit (HIR::Enum &enum_item)
     196              : {
     197          526 :   ModuleVisibility vis;
     198          526 :   if (!resolve_visibility (enum_item.get_visibility (), vis))
     199            0 :     return;
     200              : 
     201          526 :   auto &mod_vis_mapping = mappings.ast.module_visibility;
     202              : 
     203          526 :   mod_vis_mapping.insert (enum_item.get_mappings ().get_nodeid (), vis);
     204         1764 :   for (auto &variant : enum_item.get_variants ())
     205         1238 :     mod_vis_mapping.insert (variant->get_mappings ().get_nodeid (), vis);
     206              : }
     207              : 
     208              : void
     209          102 : VisibilityResolver::visit (HIR::Union &)
     210          102 : {}
     211              : 
     212              : void
     213          494 : VisibilityResolver::visit (HIR::ConstantItem &const_item)
     214              : {
     215          494 :   resolve_and_update (&const_item);
     216          494 : }
     217              : 
     218              : void
     219           74 : VisibilityResolver::visit (HIR::StaticItem &static_item)
     220              : {
     221           74 :   resolve_and_update (&static_item);
     222           74 : }
     223              : 
     224              : void
     225         4064 : VisibilityResolver::visit (HIR::Trait &trait)
     226              : {
     227         4064 :   ModuleVisibility vis;
     228         4064 :   if (!resolve_visibility (trait.get_visibility (), vis))
     229            0 :     return;
     230              : 
     231         4064 :   auto &mod_vis_mapping = mappings.ast.module_visibility;
     232         4064 :   mod_vis_mapping.insert (trait.get_mappings ().get_nodeid (), vis);
     233         7602 :   for (auto &item : trait.get_trait_items ())
     234         3538 :     mod_vis_mapping.insert (item->get_mappings ().get_nodeid (), vis);
     235              : }
     236              : 
     237              : void
     238         6347 : VisibilityResolver::visit (HIR::ImplBlock &impl)
     239              : {
     240        15708 :   for (auto &item : impl.get_impl_items ())
     241              :     {
     242         9361 :       HIR::VisItem *vis_item;
     243         9361 :       switch (item->get_impl_item_type ())
     244              :         {
     245         7869 :         case HIR::ImplItem::FUNCTION:
     246         7869 :           vis_item = static_cast<HIR::Function *> (item.get ());
     247              :           break;
     248         1422 :         case HIR::ImplItem::TYPE_ALIAS:
     249         1422 :           vis_item = static_cast<HIR::TypeAlias *> (item.get ());
     250              :           break;
     251           70 :         case HIR::ImplItem::CONSTANT:
     252           70 :           vis_item = static_cast<HIR::ConstantItem *> (item.get ());
     253              :           break;
     254            0 :         default:
     255            0 :           rust_unreachable ();
     256         9361 :           return;
     257              :         }
     258         9361 :       vis_item->accept_vis (*this);
     259              :     }
     260         6347 : }
     261              : 
     262              : void
     263         1696 : VisibilityResolver::visit (HIR::ExternBlock &)
     264         1696 : {}
     265              : 
     266              : } // namespace Privacy
     267              : } // namespace Rust
        

Generated by: LCOV version 2.5.0-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.