Skip to content

Commit d36a3c5

Browse files
Merge #1110
1110: Add Reachability visitors for items with generics r=CohenArthur a=CohenArthur This factors generics' predicates visiting in the `ReachabilityVisitor` and calls the function in other items with generic parameters Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2 parents 73e017f + ed904fe commit d36a3c5

File tree

2 files changed

+87
-42
lines changed

2 files changed

+87
-42
lines changed

gcc/rust/privacy/rust-reachability.cc

Lines changed: 74 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,41 @@ maybe_get_vis_item (std::unique_ptr<HIR::Item> &item)
3131
return static_cast<HIR::VisItem *> (item.get ());
3232
}
3333

34+
ReachLevel
35+
ReachabilityVisitor::get_reachability_level (
36+
const HIR::Visibility &item_visibility)
37+
{
38+
return item_visibility.is_public () ? current_level : ReachLevel::Unreachable;
39+
}
40+
41+
void
42+
ReachabilityVisitor::visit_generic_predicates (
43+
const std::vector<std::unique_ptr<HIR::GenericParam>> &generics,
44+
ReachLevel item_reach)
45+
{
46+
if (item_reach == ReachLevel::Unreachable)
47+
return;
48+
49+
for (const auto &generic : generics)
50+
{
51+
if (generic->get_kind () == HIR::GenericParam::TYPE)
52+
{
53+
TyTy::BaseType *generic_ty = nullptr;
54+
auto ok = ty_ctx.lookup_type (generic->get_mappings ().get_hirid (),
55+
&generic_ty);
56+
rust_assert (ok);
57+
rust_assert (generic_ty->get_kind () == TyTy::PARAM);
58+
59+
auto generic_param = static_cast<TyTy::ParamType *> (generic_ty);
60+
for (const auto &bound : generic_param->get_specified_bounds ())
61+
{
62+
const auto trait = bound.get ()->get_hir_trait_ref ();
63+
ctx.update_reachability (trait->get_mappings (), item_reach);
64+
}
65+
}
66+
}
67+
}
68+
3469
void
3570
ReachabilityVisitor::visit (HIR::Module &mod)
3671
{
@@ -56,60 +91,36 @@ ReachabilityVisitor::visit (HIR::UseDeclaration &use_decl)
5691

5792
void
5893
ReachabilityVisitor::visit (HIR::Function &func)
59-
{}
94+
{
95+
auto fn_reach = get_reachability_level (func.get_visibility ());
96+
97+
fn_reach = ctx.update_reachability (func.get_mappings (), fn_reach);
98+
visit_generic_predicates (func.get_generic_params (), fn_reach);
99+
}
60100

61101
void
62102
ReachabilityVisitor::visit (HIR::TypeAlias &type_alias)
63-
{}
103+
{
104+
auto type_reach = get_reachability_level (type_alias.get_visibility ());
105+
106+
visit_generic_predicates (type_alias.get_generic_params (), type_reach);
107+
}
64108

65109
void
66110
ReachabilityVisitor::visit (HIR::StructStruct &struct_item)
67111
{
68-
auto struct_reach = ReachLevel::Unreachable;
69-
if (struct_item.get_visibility ().is_public ())
70-
struct_reach = current_level;
112+
auto struct_reach = get_reachability_level (struct_item.get_visibility ());
71113

72114
struct_reach
73115
= ctx.update_reachability (struct_item.get_mappings (), struct_reach);
74116

75117
auto old_level = current_level;
76118
current_level = struct_reach;
77119

120+
visit_generic_predicates (struct_item.get_generic_params (), struct_reach);
121+
78122
if (struct_reach != ReachLevel::Unreachable)
79123
{
80-
for (auto &field : struct_item.get_fields ())
81-
if (field.get_visibility ().is_public ())
82-
ctx.update_reachability (field.get_mappings (), struct_reach);
83-
84-
for (auto &generic : struct_item.get_generic_params ())
85-
{
86-
switch (generic->get_kind ())
87-
{
88-
case HIR::GenericParam::LIFETIME:
89-
break;
90-
case HIR::GenericParam::TYPE:
91-
TyTy::BaseType *generic_ty = nullptr;
92-
rust_assert (
93-
ty_ctx.lookup_type (generic->get_mappings ().get_hirid (),
94-
&generic_ty));
95-
96-
if (generic_ty->get_kind () == TyTy::PARAM)
97-
{
98-
auto generic_param
99-
= static_cast<TyTy::ParamType *> (generic_ty);
100-
for (const auto &bound :
101-
generic_param->get_specified_bounds ())
102-
{
103-
const auto trait = bound.get ()->get_hir_trait_ref ();
104-
ctx.update_reachability (trait->get_mappings (),
105-
struct_reach);
106-
}
107-
}
108-
109-
break;
110-
}
111-
}
112-
113124
for (auto &field : struct_item.get_fields ())
114125
if (field.get_visibility ().is_public ())
115126
ctx.update_reachability (field.get_field_type ()->get_mappings (),
@@ -125,11 +136,22 @@ ReachabilityVisitor::visit (HIR::TupleStruct &tuple_struct)
125136

126137
void
127138
ReachabilityVisitor::visit (HIR::Enum &enum_item)
128-
{}
139+
{
140+
auto enum_reach = get_reachability_level (enum_item.get_visibility ());
141+
142+
enum_reach = ctx.update_reachability (enum_item.get_mappings (), enum_reach);
143+
visit_generic_predicates (enum_item.get_generic_params (), enum_reach);
144+
}
129145

130146
void
131147
ReachabilityVisitor::visit (HIR::Union &union_item)
132-
{}
148+
{
149+
auto union_reach = get_reachability_level (union_item.get_visibility ());
150+
151+
union_reach
152+
= ctx.update_reachability (union_item.get_mappings (), union_reach);
153+
visit_generic_predicates (union_item.get_generic_params (), union_reach);
154+
}
133155

134156
void
135157
ReachabilityVisitor::visit (HIR::ConstantItem &const_item)
@@ -141,11 +163,21 @@ ReachabilityVisitor::visit (HIR::StaticItem &static_item)
141163

142164
void
143165
ReachabilityVisitor::visit (HIR::Trait &trait)
144-
{}
166+
{
167+
auto trait_reach = get_reachability_level (trait.get_visibility ());
168+
169+
trait_reach = ctx.update_reachability (trait.get_mappings (), trait_reach);
170+
visit_generic_predicates (trait.get_generic_params (), trait_reach);
171+
}
145172

146173
void
147174
ReachabilityVisitor::visit (HIR::ImplBlock &impl)
148-
{}
175+
{
176+
auto impl_reach = get_reachability_level (impl.get_visibility ());
177+
178+
impl_reach = ctx.update_reachability (impl.get_mappings (), impl_reach);
179+
visit_generic_predicates (impl.get_generic_params (), impl_reach);
180+
}
149181

150182
void
151183
ReachabilityVisitor::visit (HIR::ExternBlock &block)

gcc/rust/privacy/rust-reachability.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ class ReachabilityVisitor : public HIR::HIRVisItemVisitor
4646
: current_level (ReachLevel::Reachable), ctx (ctx), ty_ctx (ty_ctx)
4747
{}
4848

49+
/**
50+
* Visit all the predicates of all the generic types of a given item, marking
51+
* them as reachable or not.
52+
*/
53+
void visit_generic_predicates (
54+
const std::vector<std::unique_ptr<HIR::GenericParam>> &generics,
55+
ReachLevel item_reach);
56+
57+
/**
58+
* Get the initial reach level for an item based on its visibility.
59+
*/
60+
ReachLevel get_reachability_level (const HIR::Visibility &item_visibility);
61+
4962
virtual void visit (HIR::Module &mod);
5063
virtual void visit (HIR::ExternCrate &crate);
5164
virtual void visit (HIR::UseDeclaration &use_decl);

0 commit comments

Comments
 (0)