]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
Update copyright years.
[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
40 for (auto &item : crate.items)
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
77 auto module = mappings.lookup_module (ref);
78 if (!module)
79 {
2785d591 80 invalid_path.emit ();
ca246e57
AC
81 return false;
82 }
83
84 // Fill in the resolved `DefId`
85 id = module->get_mappings ().get_defid ();
86
87 return true;
88}
89
90bool
91VisibilityResolver::resolve_visibility (const HIR::Visibility &visibility,
92 ModuleVisibility &to_resolve)
93{
94 switch (visibility.get_vis_type ())
95 {
96 case HIR::Visibility::PRIVATE:
97 to_resolve = ModuleVisibility::create_restricted (current_module);
98 return true;
99 case HIR::Visibility::PUBLIC:
100 to_resolve = ModuleVisibility::create_public ();
101 return true;
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);
107 return result;
108 }
109 default:
110 gcc_unreachable ();
111 return false;
112 }
113}
114
115void
116VisibilityResolver::resolve_and_update (const HIR::VisItem *item)
117{
118 ModuleVisibility module_vis;
119 if (!resolve_visibility (item->get_visibility (), module_vis))
120 return; // we will already have emitted errors
121
122 mappings.insert_visibility (item->get_mappings ().get_nodeid (), module_vis);
123}
124
125void
126VisibilityResolver::visit (HIR::Module &mod)
127{
128 auto old_module = current_module;
129 current_module = mod.get_mappings ().get_defid ();
130
131 for (auto &item : mod.get_items ())
132 {
133 if (item->get_hir_kind () == HIR::Node::VIS_ITEM)
134 {
135 auto vis_item = static_cast<HIR::VisItem *> (item.get ());
136 vis_item->accept_vis (*this);
137 }
138 }
139
140 current_module = old_module;
141}
142
143void
9f455ed8 144VisibilityResolver::visit (HIR::ExternCrate &)
ca246e57
AC
145{}
146
147void
9f455ed8 148VisibilityResolver::visit (HIR::UseDeclaration &)
ca246e57
AC
149{}
150
151void
152VisibilityResolver::visit (HIR::Function &func)
153{
154 resolve_and_update (&func);
155}
156
157void
158VisibilityResolver::visit (HIR::TypeAlias &type_alias)
159{
160 resolve_and_update (&type_alias);
161}
162
163void
164VisibilityResolver::visit (HIR::StructStruct &struct_item)
165{
166 resolve_and_update (&struct_item);
167}
168
169void
170VisibilityResolver::visit (HIR::TupleStruct &tuple_struct)
171{
172 resolve_and_update (&tuple_struct);
173}
174
175void
176VisibilityResolver::visit (HIR::Enum &enum_item)
177{
178 ModuleVisibility vis;
179 if (!resolve_visibility (enum_item.get_visibility (), vis))
180 return;
181
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);
185}
186
187void
9f455ed8 188VisibilityResolver::visit (HIR::Union &)
ca246e57
AC
189{}
190
191void
192VisibilityResolver::visit (HIR::ConstantItem &const_item)
193{
194 resolve_and_update (&const_item);
195}
196
197void
198VisibilityResolver::visit (HIR::StaticItem &static_item)
199{
200 resolve_and_update (&static_item);
201}
202
203void
204VisibilityResolver::visit (HIR::Trait &trait)
205{
206 ModuleVisibility vis;
207 if (!resolve_visibility (trait.get_visibility (), vis))
208 return;
209
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);
213}
214
215void
216VisibilityResolver::visit (HIR::ImplBlock &impl)
217{
218 for (auto &item : impl.get_impl_items ())
219 {
220 HIR::VisItem *vis_item;
221 switch (item->get_impl_item_type ())
222 {
223 case HIR::ImplItem::FUNCTION:
224 vis_item = static_cast<HIR::Function *> (item.get ());
225 break;
226 case HIR::ImplItem::TYPE_ALIAS:
227 vis_item = static_cast<HIR::TypeAlias *> (item.get ());
228 break;
229 case HIR::ImplItem::CONSTANT:
230 vis_item = static_cast<HIR::ConstantItem *> (item.get ());
231 break;
232 default:
233 gcc_unreachable ();
234 return;
235 }
236 vis_item->accept_vis (*this);
237 }
238}
239
240void
9f455ed8 241VisibilityResolver::visit (HIR::ExternBlock &)
ca246e57
AC
242{}
243
244} // namespace Privacy
245} // namespace Rust