Skip to content

Commit 4337aea

Browse files
Merge #1155
1155: Add base for visibility resolving r=CohenArthur a=CohenArthur This adds a new visitor whose aim is to resolve the visibility of each VisItem in a crate. The crux of the implementation will be resolving `pub restricted` items, whose module needs to be resolved using name resolution/path resolution. On top of that, we will need to add a new visitor building a "tree" of modules, with a `accessible_from` or `is_child_of` method: All children of a module get to access its items whose visibility is inherited. Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2 parents b392376 + bdd1b86 commit 4337aea

10 files changed

+352
-2
lines changed

gcc/rust/Make-lang.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ GRS_OBJS = \
9393
rust/rust-privacy-check.o \
9494
rust/rust-privacy-ctx.o \
9595
rust/rust-reachability.o \
96+
rust/rust-visibility-resolver.o \
9697
rust/rust-tyty.o \
9798
rust/rust-tyctx.o \
9899
rust/rust-tyty-bounds.o \

gcc/rust/hir/tree/rust-hir-item.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ struct FunctionParam
549549
const Analysis::NodeMapping &get_mappings () const { return mappings; }
550550
};
551551

552-
// Visibility of item - if the item has it, then it is some form of public
552+
// Visibility of an item
553553
struct Visibility
554554
{
555555
public:

gcc/rust/privacy/rust-privacy-check.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "rust-privacy-check.h"
2020
#include "rust-reachability.h"
2121
#include "rust-hir-type-check.h"
22+
#include "rust-hir-map.h"
23+
#include "rust-visibility-resolver.h"
2224

2325
extern bool
2426
saw_errors (void);
@@ -29,10 +31,16 @@ void
2931
Resolver::resolve (HIR::Crate &crate)
3032
{
3133
PrivacyContext ctx;
34+
auto mappings = Analysis::Mappings::get ();
35+
36+
auto resolver = VisibilityResolver (*mappings);
37+
resolver.go (crate);
38+
3239
auto ty_ctx = ::Rust::Resolver::TypeCheckContext::get ();
3340
auto visitor = ReachabilityVisitor (ctx, *ty_ctx);
3441

3542
const auto &items = crate.items;
43+
3644
for (auto &item : items)
3745
{
3846
if (item->get_hir_kind () == HIR::Node::VIS_ITEM)

gcc/rust/privacy/rust-privacy-check.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#ifndef RUST_PRIVACY_CHECK_H
2020
#define RUST_PRIVACY_CHECK_H
2121

22-
#include "rust-hir-map.h"
2322
#include "rust-hir.h"
2423
#include "rust-hir-expr.h"
2524
#include "rust-hir-stmt.h"
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright (C) 2020-2022 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-mapping-common.h"
20+
21+
namespace Rust {
22+
namespace Privacy {
23+
24+
/**
25+
* Visibility class related specifically to DefIds. This class allows defining
26+
* the visibility of an item with regard to a specific module.
27+
*/
28+
class ModuleVisibility
29+
{
30+
public:
31+
enum Type
32+
{
33+
Unknown,
34+
Private,
35+
Public,
36+
Restricted,
37+
};
38+
39+
ModuleVisibility () : kind (Unknown), module_id (UNKNOWN_DEFID) {}
40+
41+
static ModuleVisibility create_restricted (DefId module_id)
42+
{
43+
return ModuleVisibility (Type::Restricted, module_id);
44+
}
45+
46+
static ModuleVisibility create_public ()
47+
{
48+
return ModuleVisibility (Type::Public, UNKNOWN_DEFID);
49+
}
50+
51+
Type get_kind () const { return kind; }
52+
53+
const DefId &get_module_id () const { return module_id; }
54+
55+
private:
56+
ModuleVisibility (Type kind, DefId module_id)
57+
: kind (kind), module_id (module_id)
58+
{}
59+
60+
Type kind;
61+
DefId module_id;
62+
};
63+
} // namespace Privacy
64+
} // namespace Rust

gcc/rust/privacy/rust-reachability.h

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

49+
// FIXME: Add `go` method which takes an `HIR::Crate &` as argument
50+
4951
/**
5052
* Visit all the predicates of all the generic types of a given item, marking
5153
* them as reachable or not.
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
// Copyright (C) 2020-2022 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+
24+
namespace Rust {
25+
namespace Privacy {
26+
27+
VisibilityResolver::VisibilityResolver (Analysis::Mappings &mappings)
28+
: mappings (mappings)
29+
{}
30+
31+
void
32+
VisibilityResolver::go (HIR::Crate &crate)
33+
{
34+
module_stack.push_back (crate.get_mappings ().get_defid ());
35+
mappings.insert_visibility (crate.get_mappings ().get_defid (),
36+
ModuleVisibility::create_public ());
37+
38+
for (auto &item : crate.items)
39+
{
40+
if (item->get_hir_kind () == HIR::Node::VIS_ITEM)
41+
{
42+
auto vis_item = static_cast<HIR::VisItem *> (item.get ());
43+
vis_item->accept_vis (*this);
44+
}
45+
}
46+
}
47+
48+
bool
49+
VisibilityResolver::resolve_visibility (const HIR::Visibility &visibility,
50+
ModuleVisibility &to_resolve)
51+
{
52+
switch (visibility.get_vis_type ())
53+
{
54+
case HIR::Visibility::PRIVATE:
55+
to_resolve = ModuleVisibility::create_restricted (peek_module ());
56+
return true;
57+
case HIR::Visibility::PUBLIC:
58+
// FIXME: We need to handle the restricted path here
59+
// FIXME: We also need to handle 2015 vs 2018 edition conflicts
60+
to_resolve = ModuleVisibility::create_public ();
61+
return true;
62+
default:
63+
return false;
64+
}
65+
}
66+
67+
DefId
68+
VisibilityResolver::peek_module ()
69+
{
70+
// We're always inserting a top module - the crate
71+
// But we have to check otherwise `.back()` is UB
72+
rust_assert (!module_stack.empty ());
73+
74+
return module_stack.back ();
75+
}
76+
77+
void
78+
VisibilityResolver::visit (HIR::Module &mod)
79+
{
80+
module_stack.push_back (mod.get_mappings ().get_defid ());
81+
82+
for (auto &item : mod.get_items ())
83+
{
84+
if (item->get_hir_kind () == HIR::Node::VIS_ITEM)
85+
{
86+
auto vis_item = static_cast<HIR::VisItem *> (item.get ());
87+
vis_item->accept_vis (*this);
88+
}
89+
}
90+
91+
module_stack.pop_back ();
92+
}
93+
94+
void
95+
VisibilityResolver::visit (HIR::ExternCrate &crate)
96+
{}
97+
98+
void
99+
VisibilityResolver::visit (HIR::UseDeclaration &use_decl)
100+
{}
101+
102+
void
103+
VisibilityResolver::visit (HIR::Function &func)
104+
{}
105+
106+
void
107+
VisibilityResolver::visit (HIR::TypeAlias &type_alias)
108+
{}
109+
110+
void
111+
VisibilityResolver::visit (HIR::StructStruct &struct_item)
112+
{}
113+
114+
void
115+
VisibilityResolver::visit (HIR::TupleStruct &tuple_struct)
116+
{}
117+
118+
void
119+
VisibilityResolver::visit (HIR::Enum &enum_item)
120+
{
121+
ModuleVisibility vis;
122+
if (!resolve_visibility (enum_item.get_visibility (), vis))
123+
return;
124+
125+
mappings.insert_visibility (enum_item.get_mappings ().get_defid (), vis);
126+
for (auto &variant : enum_item.get_variants ())
127+
mappings.insert_visibility (variant->get_mappings ().get_defid (), vis);
128+
}
129+
130+
void
131+
VisibilityResolver::visit (HIR::Union &union_item)
132+
{}
133+
134+
void
135+
VisibilityResolver::visit (HIR::ConstantItem &const_item)
136+
{}
137+
138+
void
139+
VisibilityResolver::visit (HIR::StaticItem &static_item)
140+
{}
141+
142+
void
143+
VisibilityResolver::visit (HIR::Trait &trait)
144+
{
145+
ModuleVisibility vis;
146+
if (!resolve_visibility (trait.get_visibility (), vis))
147+
return;
148+
149+
mappings.insert_visibility (trait.get_mappings ().get_defid (), vis);
150+
for (auto &item : trait.get_trait_items ())
151+
mappings.insert_visibility (item->get_mappings ().get_defid (), vis);
152+
}
153+
154+
void
155+
VisibilityResolver::visit (HIR::ImplBlock &impl)
156+
{}
157+
158+
void
159+
VisibilityResolver::visit (HIR::ExternBlock &block)
160+
{}
161+
162+
} // namespace Privacy
163+
} // namespace Rust
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright (C) 2020-2022 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+
#ifndef RUST_VISIBILITY_H
20+
#define RUST_VISIBILITY_H
21+
22+
#include "rust-hir.h"
23+
#include "rust-hir-expr.h"
24+
#include "rust-hir-stmt.h"
25+
#include "rust-hir-item.h"
26+
#include "rust-hir-map.h"
27+
#include "rust-hir-visitor.h"
28+
29+
namespace Rust {
30+
namespace Privacy {
31+
32+
class VisibilityResolver : public HIR::HIRVisItemVisitor
33+
{
34+
public:
35+
VisibilityResolver (Analysis::Mappings &mappings);
36+
37+
/**
38+
* Perform visibility resolving on an entire crate
39+
*/
40+
void go (HIR::Crate &crate);
41+
42+
/**
43+
* Resolve the visibility of an item to its ModuleVisibility. This function
44+
* emits errors if necessary. The contents of the to_resolve parameter will be
45+
* overwritten on success.
46+
*
47+
* @param visibility Visibility of the item to resolve
48+
* @param to_resolve ModuleVisibility reference to fill on success.
49+
*
50+
* @return false on error, true if the resolving was successful.
51+
*/
52+
bool resolve_visibility (const HIR::Visibility &visibility,
53+
ModuleVisibility &to_resolve);
54+
55+
/**
56+
* Get the DefId of the parent module we are currently visiting.
57+
*
58+
* @return UNKNOWN_DEFID if the module stack is empty, a valid `DefId`
59+
* otherwise
60+
*/
61+
DefId peek_module ();
62+
63+
virtual void visit (HIR::Module &mod);
64+
virtual void visit (HIR::ExternCrate &crate);
65+
virtual void visit (HIR::UseDeclaration &use_decl);
66+
virtual void visit (HIR::Function &func);
67+
virtual void visit (HIR::TypeAlias &type_alias);
68+
virtual void visit (HIR::StructStruct &struct_item);
69+
virtual void visit (HIR::TupleStruct &tuple_struct);
70+
virtual void visit (HIR::Enum &enum_item);
71+
virtual void visit (HIR::Union &union_item);
72+
virtual void visit (HIR::ConstantItem &const_item);
73+
virtual void visit (HIR::StaticItem &static_item);
74+
virtual void visit (HIR::Trait &trait);
75+
virtual void visit (HIR::ImplBlock &impl);
76+
virtual void visit (HIR::ExternBlock &block);
77+
78+
private:
79+
/* Mappings to insert visibilities into */
80+
Analysis::Mappings &mappings;
81+
82+
/* Stack of modules visited by this visitor */
83+
std::vector<DefId> module_stack;
84+
};
85+
86+
} // namespace Privacy
87+
} // namespace Rust
88+
89+
#endif // !RUST_VISIBILITY_H

0 commit comments

Comments
 (0)