]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
libobjc: Fix typos
[thirdparty/gcc.git] / gcc / rust / checks / errors / privacy / rust-visibility-resolver.cc
CommitLineData
a945c346 1// Copyright (C) 2020-2024 Free Software Foundation, Inc.
ca246e57
AC
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
24namespace Rust {
25namespace Privacy {
26
27VisibilityResolver::VisibilityResolver (Analysis::Mappings &mappings,
28 Resolver::Resolver &resolver)
29 : mappings (mappings), resolver (resolver)
30{}
31
32void
33VisibilityResolver::go (HIR::Crate &crate)
34{
35 mappings.insert_visibility (crate.get_mappings ().get_nodeid (),
36 ModuleVisibility::create_public ());
37
38 current_module = crate.get_mappings ().get_defid ();
39
11fbade5 40 for (auto &item : crate.get_items ())
ca246e57
AC
41 {
42 if (item->get_hir_kind () == HIR::Node::VIS_ITEM)
43 {
44 auto vis_item = static_cast<HIR::VisItem *> (item.get ());
45 vis_item->accept_vis (*this);
46 }
47 }
48}
49
50bool
51VisibilityResolver::resolve_module_path (const HIR::SimplePath &restriction,
52 DefId &id)
53{
54 // We need, from the restriction, to figure out the actual Module it
55 // belongs to.
56
57 NodeId ast_node_id = restriction.get_mappings ().get_nodeid ();
58
59 auto invalid_path
60 = Error (restriction.get_locus (),
61 "cannot use non-module path as privacy restrictor");
62
63 NodeId ref_node_id = UNKNOWN_NODEID;
64 if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
65 {
2785d591 66 invalid_path.emit ();
ca246e57
AC
67 return false;
68 }
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
72 // present?
73
74 HirId ref;
75 rust_assert (mappings.lookup_node_to_hir (ref_node_id, &ref));
76
d1e329af
AC
77 auto crate = mappings.get_ast_crate (mappings.get_current_crate ());
78
79 // we may be dealing with pub(crate)
80 if (ref_node_id == crate.get_node_id ())
81 // FIXME: What do we do here? There isn't a DefId for the Crate, so can we
82 // actually do anything?
83 // We basically want to return true always but just when exporting export
84 // these items as private?
85 return true;
86
ca246e57
AC
87 auto module = mappings.lookup_module (ref);
88 if (!module)
89 {
2785d591 90 invalid_path.emit ();
ca246e57
AC
91 return false;
92 }
93
94 // Fill in the resolved `DefId`
95 id = module->get_mappings ().get_defid ();
96
97 return true;
98}
99
100bool
101VisibilityResolver::resolve_visibility (const HIR::Visibility &visibility,
102 ModuleVisibility &to_resolve)
103{
104 switch (visibility.get_vis_type ())
105 {
106 case HIR::Visibility::PRIVATE:
107 to_resolve = ModuleVisibility::create_restricted (current_module);
108 return true;
109 case HIR::Visibility::PUBLIC:
110 to_resolve = ModuleVisibility::create_public ();
111 return true;
112 case HIR::Visibility::RESTRICTED: {
113 // FIXME: We also need to handle 2015 vs 2018 edition conflicts
114 auto id = UNKNOWN_DEFID;
115 auto result = resolve_module_path (visibility.get_path (), id);
116 to_resolve = ModuleVisibility::create_restricted (id);
117 return result;
118 }
119 default:
93866b6a 120 rust_unreachable ();
ca246e57
AC
121 return false;
122 }
123}
124
125void
126VisibilityResolver::resolve_and_update (const HIR::VisItem *item)
127{
128 ModuleVisibility module_vis;
129 if (!resolve_visibility (item->get_visibility (), module_vis))
130 return; // we will already have emitted errors
131
132 mappings.insert_visibility (item->get_mappings ().get_nodeid (), module_vis);
133}
134
135void
136VisibilityResolver::visit (HIR::Module &mod)
137{
138 auto old_module = current_module;
139 current_module = mod.get_mappings ().get_defid ();
140
141 for (auto &item : mod.get_items ())
142 {
143 if (item->get_hir_kind () == HIR::Node::VIS_ITEM)
144 {
145 auto vis_item = static_cast<HIR::VisItem *> (item.get ());
146 vis_item->accept_vis (*this);
147 }
148 }
149
150 current_module = old_module;
151}
152
153void
9f455ed8 154VisibilityResolver::visit (HIR::ExternCrate &)
ca246e57
AC
155{}
156
157void
9f455ed8 158VisibilityResolver::visit (HIR::UseDeclaration &)
ca246e57
AC
159{}
160
161void
162VisibilityResolver::visit (HIR::Function &func)
163{
164 resolve_and_update (&func);
165}
166
167void
168VisibilityResolver::visit (HIR::TypeAlias &type_alias)
169{
170 resolve_and_update (&type_alias);
171}
172
173void
174VisibilityResolver::visit (HIR::StructStruct &struct_item)
175{
176 resolve_and_update (&struct_item);
177}
178
179void
180VisibilityResolver::visit (HIR::TupleStruct &tuple_struct)
181{
182 resolve_and_update (&tuple_struct);
183}
184
185void
186VisibilityResolver::visit (HIR::Enum &enum_item)
187{
188 ModuleVisibility vis;
189 if (!resolve_visibility (enum_item.get_visibility (), vis))
190 return;
191
192 mappings.insert_visibility (enum_item.get_mappings ().get_nodeid (), vis);
193 for (auto &variant : enum_item.get_variants ())
194 mappings.insert_visibility (variant->get_mappings ().get_nodeid (), vis);
195}
196
197void
9f455ed8 198VisibilityResolver::visit (HIR::Union &)
ca246e57
AC
199{}
200
201void
202VisibilityResolver::visit (HIR::ConstantItem &const_item)
203{
204 resolve_and_update (&const_item);
205}
206
207void
208VisibilityResolver::visit (HIR::StaticItem &static_item)
209{
210 resolve_and_update (&static_item);
211}
212
213void
214VisibilityResolver::visit (HIR::Trait &trait)
215{
216 ModuleVisibility vis;
217 if (!resolve_visibility (trait.get_visibility (), vis))
218 return;
219
220 mappings.insert_visibility (trait.get_mappings ().get_nodeid (), vis);
221 for (auto &item : trait.get_trait_items ())
222 mappings.insert_visibility (item->get_mappings ().get_nodeid (), vis);
223}
224
225void
226VisibilityResolver::visit (HIR::ImplBlock &impl)
227{
228 for (auto &item : impl.get_impl_items ())
229 {
230 HIR::VisItem *vis_item;
231 switch (item->get_impl_item_type ())
232 {
233 case HIR::ImplItem::FUNCTION:
234 vis_item = static_cast<HIR::Function *> (item.get ());
235 break;
236 case HIR::ImplItem::TYPE_ALIAS:
237 vis_item = static_cast<HIR::TypeAlias *> (item.get ());
238 break;
239 case HIR::ImplItem::CONSTANT:
240 vis_item = static_cast<HIR::ConstantItem *> (item.get ());
241 break;
242 default:
93866b6a 243 rust_unreachable ();
ca246e57
AC
244 return;
245 }
246 vis_item->accept_vis (*this);
247 }
248}
249
250void
9f455ed8 251VisibilityResolver::visit (HIR::ExternBlock &)
ca246e57
AC
252{}
253
254} // namespace Privacy
255} // namespace Rust