1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 // This file is part of GCC.
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
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
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/>.
19 #include "rust-visibility-resolver.h"
22 #include "rust-hir-item.h"
27 VisibilityResolver::VisibilityResolver (Analysis::Mappings
&mappings
,
28 Resolver::Resolver
&resolver
)
29 : mappings (mappings
), resolver (resolver
)
33 VisibilityResolver::go (HIR::Crate
&crate
)
35 mappings
.insert_visibility (crate
.get_mappings ().get_nodeid (),
36 ModuleVisibility::create_public ());
38 current_module
= crate
.get_mappings ().get_defid ();
40 for (auto &item
: crate
.items
)
42 if (item
->get_hir_kind () == HIR::Node::VIS_ITEM
)
44 auto vis_item
= static_cast<HIR::VisItem
*> (item
.get ());
45 vis_item
->accept_vis (*this);
51 VisibilityResolver::resolve_module_path (const HIR::SimplePath
&restriction
,
54 // We need, from the restriction, to figure out the actual Module it
57 NodeId ast_node_id
= restriction
.get_mappings ().get_nodeid ();
60 = Error (restriction
.get_locus (),
61 "cannot use non-module path as privacy restrictor");
63 NodeId ref_node_id
= UNKNOWN_NODEID
;
64 if (!resolver
.lookup_resolved_name (ast_node_id
, &ref_node_id
))
69 // FIXME: Add a hint here if we can find the path in another scope, such as
70 // a type or something else
71 // TODO: For the hint, can we point to the original item's definition if
75 rust_assert (mappings
.lookup_node_to_hir (ref_node_id
, &ref
));
77 auto module
= mappings
.lookup_module (ref
);
84 // Fill in the resolved `DefId`
85 id
= module
->get_mappings ().get_defid ();
91 VisibilityResolver::resolve_visibility (const HIR::Visibility
&visibility
,
92 ModuleVisibility
&to_resolve
)
94 switch (visibility
.get_vis_type ())
96 case HIR::Visibility::PRIVATE
:
97 to_resolve
= ModuleVisibility::create_restricted (current_module
);
99 case HIR::Visibility::PUBLIC
:
100 to_resolve
= ModuleVisibility::create_public ();
102 case HIR::Visibility::RESTRICTED
: {
103 // FIXME: We also need to handle 2015 vs 2018 edition conflicts
104 auto id
= UNKNOWN_DEFID
;
105 auto result
= resolve_module_path (visibility
.get_path (), id
);
106 to_resolve
= ModuleVisibility::create_restricted (id
);
116 VisibilityResolver::resolve_and_update (const HIR::VisItem
*item
)
118 ModuleVisibility module_vis
;
119 if (!resolve_visibility (item
->get_visibility (), module_vis
))
120 return; // we will already have emitted errors
122 mappings
.insert_visibility (item
->get_mappings ().get_nodeid (), module_vis
);
126 VisibilityResolver::visit (HIR::Module
&mod
)
128 auto old_module
= current_module
;
129 current_module
= mod
.get_mappings ().get_defid ();
131 for (auto &item
: mod
.get_items ())
133 if (item
->get_hir_kind () == HIR::Node::VIS_ITEM
)
135 auto vis_item
= static_cast<HIR::VisItem
*> (item
.get ());
136 vis_item
->accept_vis (*this);
140 current_module
= old_module
;
144 VisibilityResolver::visit (HIR::ExternCrate
&)
148 VisibilityResolver::visit (HIR::UseDeclaration
&)
152 VisibilityResolver::visit (HIR::Function
&func
)
154 resolve_and_update (&func
);
158 VisibilityResolver::visit (HIR::TypeAlias
&type_alias
)
160 resolve_and_update (&type_alias
);
164 VisibilityResolver::visit (HIR::StructStruct
&struct_item
)
166 resolve_and_update (&struct_item
);
170 VisibilityResolver::visit (HIR::TupleStruct
&tuple_struct
)
172 resolve_and_update (&tuple_struct
);
176 VisibilityResolver::visit (HIR::Enum
&enum_item
)
178 ModuleVisibility vis
;
179 if (!resolve_visibility (enum_item
.get_visibility (), vis
))
182 mappings
.insert_visibility (enum_item
.get_mappings ().get_nodeid (), vis
);
183 for (auto &variant
: enum_item
.get_variants ())
184 mappings
.insert_visibility (variant
->get_mappings ().get_nodeid (), vis
);
188 VisibilityResolver::visit (HIR::Union
&)
192 VisibilityResolver::visit (HIR::ConstantItem
&const_item
)
194 resolve_and_update (&const_item
);
198 VisibilityResolver::visit (HIR::StaticItem
&static_item
)
200 resolve_and_update (&static_item
);
204 VisibilityResolver::visit (HIR::Trait
&trait
)
206 ModuleVisibility vis
;
207 if (!resolve_visibility (trait
.get_visibility (), vis
))
210 mappings
.insert_visibility (trait
.get_mappings ().get_nodeid (), vis
);
211 for (auto &item
: trait
.get_trait_items ())
212 mappings
.insert_visibility (item
->get_mappings ().get_nodeid (), vis
);
216 VisibilityResolver::visit (HIR::ImplBlock
&impl
)
218 for (auto &item
: impl
.get_impl_items ())
220 HIR::VisItem
*vis_item
;
221 switch (item
->get_impl_item_type ())
223 case HIR::ImplItem::FUNCTION
:
224 vis_item
= static_cast<HIR::Function
*> (item
.get ());
226 case HIR::ImplItem::TYPE_ALIAS
:
227 vis_item
= static_cast<HIR::TypeAlias
*> (item
.get ());
229 case HIR::ImplItem::CONSTANT
:
230 vis_item
= static_cast<HIR::ConstantItem
*> (item
.get ());
236 vis_item
->accept_vis (*this);
241 VisibilityResolver::visit (HIR::ExternBlock
&)
244 } // namespace Privacy