aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2022-04-29 13:48:34 +0200
committerArthur Cohen <arthur.cohen@embecosm.com>2022-05-05 14:07:36 +0200
commit88c20f5e1d59b691b8e8cfbd550206a39bf9727b (patch)
tree49ebe0980c3753cdba5edb8daa344ac11804820f /gcc
parent52b5286a69d86a36e279bc636cc41cbdd6795dee (diff)
downloadgcc-88c20f5e1d59b691b8e8cfbd550206a39bf9727b.zip
gcc-88c20f5e1d59b691b8e8cfbd550206a39bf9727b.tar.gz
gcc-88c20f5e1d59b691b8e8cfbd550206a39bf9727b.tar.bz2
privacy: Add base for resolving SimplePaths to Modules
This also fixes the missing kind in HIR::Visibility. Having both `pub` and `pub restricted` as a single variant in the HIR::Visibility::Kind enum was a mistake, as it cause the path resolver to be triggered for `pub` visibilities which do not refer to any paths. Finally, erroneous calls to Visibility::create_error() are removed. This caused a lot of ICEs now that the Visibility lowering logic is fixed
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/hir/rust-ast-lower.cc2
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h14
-rw-r--r--gcc/rust/hir/tree/rust-hir-path.h2
-rw-r--r--gcc/rust/parse/rust-parse-impl.h14
-rw-r--r--gcc/rust/privacy/rust-privacy-check.cc6
-rw-r--r--gcc/rust/privacy/rust-privacy-common.h1
-rw-r--r--gcc/rust/privacy/rust-visibility-resolver.cc70
-rw-r--r--gcc/rust/privacy/rust-visibility-resolver.h16
-rw-r--r--gcc/testsuite/rust/compile/pub_restricted_1.rs5
9 files changed, 97 insertions, 33 deletions
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index a385051..d861207 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/hir/rust-ast-lower.cc
@@ -46,7 +46,7 @@ translate_visibility (const AST::Visibility &vis)
case AST::Visibility::PUB_CRATE:
case AST::Visibility::PUB_SUPER:
case AST::Visibility::PUB_IN_PATH:
- return Visibility (Visibility::VisType::PUBLIC,
+ return Visibility (Visibility::VisType::RESTRICTED,
ASTLoweringSimplePath::translate (vis.get_path ()));
break;
}
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 5f664af..109a5c2 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -557,6 +557,7 @@ public:
{
PRIVATE,
PUBLIC,
+ RESTRICTED,
ERROR,
};
@@ -568,7 +569,7 @@ private:
public:
Visibility (VisType vis_type,
- HIR::SimplePath path = HIR::SimplePath::create_error ())
+ HIR::SimplePath path = HIR::SimplePath::create_empty ())
: vis_type (vis_type), path (std::move (path))
{}
@@ -578,14 +579,23 @@ public:
// Does the current visibility refer to a simple `pub <item>` entirely public
bool is_public () const { return vis_type == PUBLIC; }
+ // Is the current visibility public restricted to a certain path
+ bool is_restricted () const { return vis_type == RESTRICTED; }
+
// Creates an error visibility.
static Visibility create_error ()
{
- return Visibility (ERROR, HIR::SimplePath::create_error ());
+ return Visibility (ERROR, HIR::SimplePath::create_empty ());
}
VisType get_vis_type () const { return vis_type; }
+ const HIR::SimplePath &get_path () const
+ {
+ rust_assert (!is_error ());
+ return path;
+ }
+
std::string as_string () const;
};
diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h
index d153eae..b18bf1d 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -969,7 +969,7 @@ public:
: segments (std::move (segments)), mappings (mappings), locus (locus)
{}
- static HIR::SimplePath create_error ()
+ static HIR::SimplePath create_empty ()
{
return HIR::SimplePath ({}, Analysis::NodeMapping::get_error (),
Location ());
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 23ab32c..e76bdd8 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -5402,7 +5402,7 @@ Parser<ManagedTokenSource>::parse_inherent_impl_item ()
case FN_TOK:
// function or method
return parse_inherent_impl_function_or_method (
- AST::Visibility::create_error (), std::move (outer_attrs));
+ AST::Visibility::create_private (), std::move (outer_attrs));
case CONST:
/* lookahead to resolve production - could be function/method or const
* item */
@@ -5412,13 +5412,13 @@ Parser<ManagedTokenSource>::parse_inherent_impl_item ()
{
case IDENTIFIER:
case UNDERSCORE:
- return parse_const_item (AST::Visibility::create_error (),
+ return parse_const_item (AST::Visibility::create_private (),
std::move (outer_attrs));
case UNSAFE:
case EXTERN_TOK:
case FN_TOK:
return parse_inherent_impl_function_or_method (
- AST::Visibility::create_error (), std::move (outer_attrs));
+ AST::Visibility::create_private (), std::move (outer_attrs));
default:
add_error (Error (t->get_locus (),
"unexpected token %qs in some sort of const item "
@@ -5572,7 +5572,7 @@ Parser<ManagedTokenSource>::parse_trait_impl_item ()
// these seem to be SimplePath tokens, so this is a macro invocation semi
return parse_macro_invocation_semi (std::move (outer_attrs));
case TYPE:
- return parse_type_alias (AST::Visibility::create_error (),
+ return parse_type_alias (AST::Visibility::create_private (),
std::move (outer_attrs));
case PUB: {
// visibility, so not a macro invocation semi - must be constant,
@@ -5631,7 +5631,7 @@ Parser<ManagedTokenSource>::parse_trait_impl_item ()
case FN_TOK:
// function or method
return parse_trait_impl_function_or_method (
- AST::Visibility::create_error (), std::move (outer_attrs));
+ AST::Visibility::create_private (), std::move (outer_attrs));
case CONST:
// lookahead to resolve production - could be function/method or const
// item
@@ -5641,13 +5641,13 @@ Parser<ManagedTokenSource>::parse_trait_impl_item ()
{
case IDENTIFIER:
case UNDERSCORE:
- return parse_const_item (AST::Visibility::create_error (),
+ return parse_const_item (AST::Visibility::create_private (),
std::move (outer_attrs));
case UNSAFE:
case EXTERN_TOK:
case FN_TOK:
return parse_trait_impl_function_or_method (
- AST::Visibility::create_error (), std::move (outer_attrs));
+ AST::Visibility::create_private (), std::move (outer_attrs));
default:
add_error (Error (
t->get_locus (),
diff --git a/gcc/rust/privacy/rust-privacy-check.cc b/gcc/rust/privacy/rust-privacy-check.cc
index ccfed2c..ed90c7c 100644
--- a/gcc/rust/privacy/rust-privacy-check.cc
+++ b/gcc/rust/privacy/rust-privacy-check.cc
@@ -20,6 +20,7 @@
#include "rust-reachability.h"
#include "rust-hir-type-check.h"
#include "rust-hir-map.h"
+#include "rust-name-resolver.h"
#include "rust-visibility-resolver.h"
extern bool
@@ -32,9 +33,10 @@ Resolver::resolve (HIR::Crate &crate)
{
PrivacyContext ctx;
auto mappings = Analysis::Mappings::get ();
+ auto resolver = Rust::Resolver::Resolver::get ();
- auto resolver = VisibilityResolver (*mappings);
- resolver.go (crate);
+ auto visibility_resolver = VisibilityResolver (*mappings, *resolver);
+ visibility_resolver.go (crate);
auto ty_ctx = ::Rust::Resolver::TypeCheckContext::get ();
auto visitor = ReachabilityVisitor (ctx, *ty_ctx);
diff --git a/gcc/rust/privacy/rust-privacy-common.h b/gcc/rust/privacy/rust-privacy-common.h
index 145eac7..a47992f 100644
--- a/gcc/rust/privacy/rust-privacy-common.h
+++ b/gcc/rust/privacy/rust-privacy-common.h
@@ -51,6 +51,7 @@ public:
Type get_kind () const { return kind; }
const DefId &get_module_id () const { return module_id; }
+ DefId &get_module_id () { return module_id; }
private:
ModuleVisibility (Type kind, DefId module_id)
diff --git a/gcc/rust/privacy/rust-visibility-resolver.cc b/gcc/rust/privacy/rust-visibility-resolver.cc
index 3ab6085..d2e75c2 100644
--- a/gcc/rust/privacy/rust-visibility-resolver.cc
+++ b/gcc/rust/privacy/rust-visibility-resolver.cc
@@ -24,8 +24,9 @@
namespace Rust {
namespace Privacy {
-VisibilityResolver::VisibilityResolver (Analysis::Mappings &mappings)
- : mappings (mappings)
+VisibilityResolver::VisibilityResolver (Analysis::Mappings &mappings,
+ Resolver::Resolver &resolver)
+ : mappings (mappings), resolver (resolver)
{}
void
@@ -45,16 +46,56 @@ VisibilityResolver::go (HIR::Crate &crate)
}
}
-// FIXME: At this point in the pipeline, we should not be dealing with
-// `AST::SimplePath`s anymore! We need to be dealing with their "resolved
-// counterpart", so probably a NodeId/HirId/DefId.
+bool
+VisibilityResolver::resolve_module_path (const HIR::SimplePath &restriction,
+ DefId &id)
+{
+ // We need, from the restriction, to figure out the actual Module it
+ // belongs to.
+
+ NodeId ast_node_id = restriction.get_mappings ().get_nodeid ();
+
+ auto invalid_path
+ = Error (restriction.get_locus (),
+ "cannot use non-module path as privacy restrictor");
+
+ NodeId ref_node_id = UNKNOWN_NODEID;
+ if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+ {
+ invalid_path.emit_error ();
+ return false;
+ }
+ // FIXME: Add a hint here if we can find the path in another scope, such as
+ // a type or something else
+ // TODO: For the hint, can we point to the original item's definition if
+ // present?
+
+ Resolver::Definition def;
+ rust_assert (resolver.lookup_definition (ref_node_id, &def));
+
+ // FIXME: Is that what we want?
+ ref_node_id = def.parent;
-// static bool
-// resolve_module_path (std::vector<HIR::Module> &module_stack,
-// const AST::SimplePath &restriction, DefId &id)
-// {
-// return false;
-// }
+ HirId ref;
+ rust_assert (
+ mappings.lookup_node_to_hir (restriction.get_mappings ().get_crate_num (),
+ ref_node_id, &ref));
+
+ auto module
+ = mappings.lookup_module (restriction.get_mappings ().get_crate_num (),
+ ref);
+
+ if (!module)
+ {
+ invalid_path.emit_error ();
+ return false;
+ }
+
+ // Fill in the resolved `DefId`
+ id = module->get_mappings ().get_defid ();
+
+ return true;
+}
bool
VisibilityResolver::resolve_visibility (const HIR::Visibility &visibility,
@@ -66,11 +107,14 @@ VisibilityResolver::resolve_visibility (const HIR::Visibility &visibility,
to_resolve = ModuleVisibility::create_restricted (peek_module ());
return true;
case HIR::Visibility::PUBLIC:
- // FIXME: We need to handle the restricted path here
- // FIXME: We also need to handle 2015 vs 2018 edition conflicts
to_resolve = ModuleVisibility::create_public ();
return true;
+ case HIR::Visibility::RESTRICTED:
+ to_resolve = ModuleVisibility::create_public ();
+ return resolve_module_path (visibility.get_path (),
+ to_resolve.get_module_id ());
default:
+ gcc_unreachable ();
return false;
}
}
diff --git a/gcc/rust/privacy/rust-visibility-resolver.h b/gcc/rust/privacy/rust-visibility-resolver.h
index 16fb42f..89e6e2b 100644
--- a/gcc/rust/privacy/rust-visibility-resolver.h
+++ b/gcc/rust/privacy/rust-visibility-resolver.h
@@ -24,6 +24,7 @@
#include "rust-hir-stmt.h"
#include "rust-hir-item.h"
#include "rust-hir-map.h"
+#include "rust-name-resolver.h"
#include "rust-hir-visitor.h"
namespace Rust {
@@ -32,7 +33,8 @@ namespace Privacy {
class VisibilityResolver : public HIR::HIRVisItemVisitor
{
public:
- VisibilityResolver (Analysis::Mappings &mappings);
+ VisibilityResolver (Analysis::Mappings &mappings,
+ Rust::Resolver::Resolver &resolver);
/**
* Perform visibility resolving on an entire crate
@@ -40,6 +42,12 @@ public:
void go (HIR::Crate &crate);
/**
+ * Resolve a path to the module it refers
+ */
+ bool resolve_module_path (const HIR::SimplePath &restriction,
+ DefId &to_resolve);
+
+ /**
* Resolve the visibility of an item to its ModuleVisibility. This function
* emits errors if necessary. The contents of the to_resolve parameter will be
* overwritten on success.
@@ -84,11 +92,11 @@ public:
virtual void visit (HIR::ExternBlock &block);
private:
- /* Mappings to insert visibilities into */
- Analysis::Mappings &mappings;
-
/* Stack of modules visited by this visitor */
std::vector<DefId> module_stack;
+
+ Analysis::Mappings &mappings;
+ Rust::Resolver::Resolver &resolver;
};
} // namespace Privacy
diff --git a/gcc/testsuite/rust/compile/pub_restricted_1.rs b/gcc/testsuite/rust/compile/pub_restricted_1.rs
index 01fb65e..9bda968 100644
--- a/gcc/testsuite/rust/compile/pub_restricted_1.rs
+++ b/gcc/testsuite/rust/compile/pub_restricted_1.rs
@@ -1,12 +1,11 @@
pub mod foo {
pub mod bar {
pub fn baz() {}
+
+ pub(in foo::bar) struct A0;
}
}
-// this is invalid Rust: We just want to make sure the paths get resolved properly
-pub(in foo::bar::baz) struct A0;
-
pub(in foo::fah::baz) struct A1; // { dg-error "cannot find simple path segment .fah." }
pub(in fro::bulator::saindoux) struct A2; // { dg-error "cannot find simple path segment .fro." }
pub(in foo::bar::saindoux) struct A3; // { dg-error "cannot find simple path segment .saindoux." }