public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] ast: resolve: Implement `resolve_visibility` method
@ 2022-06-08 12:40 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 12:40 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:1c56e969a647a4c8192ac8cb747f668acf22da7b

commit 1c56e969a647a4c8192ac8cb747f668acf22da7b
Author: Arthur Cohen <arthur.cohen@embecosm.com>
Date:   Tue Apr 26 10:30:44 2022 +0200

    ast: resolve: Implement `resolve_visibility` method

Diff:
---
 gcc/rust/ast/rust-item.h                       |  1 +
 gcc/rust/resolve/rust-ast-resolve-base.cc      | 18 ++++-
 gcc/rust/resolve/rust-ast-resolve-item.cc      | 41 +++++++++++
 gcc/rust/resolve/rust-ast-resolve-path.cc      | 97 ++++++++++----------------
 gcc/testsuite/rust/compile/pub_restricted_1.rs | 14 ++++
 5 files changed, 109 insertions(+), 62 deletions(-)

diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 5d1e0d63565..9dc61a881c8 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -701,6 +701,7 @@ public:
 
   std::string as_string () const;
   const SimplePath &get_path () const { return in_path; }
+  SimplePath &get_path () { return in_path; }
 
 protected:
   // Clone function implementation - not currently virtual but may be if
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc b/gcc/rust/resolve/rust-ast-resolve-base.cc
index d1b3885837b..2a86618e043 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-base.cc
@@ -17,15 +17,27 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "rust-ast-resolve-base.h"
+#include "rust-ast-resolve-expr.h"
+#include "rust-ast-resolve-path.h"
+#include "rust-item.h"
 
 namespace Rust {
 namespace Resolver {
 
 bool
-resolve_visibility (const AST::Visibility &vis)
+ResolverBase::resolve_visibility (const AST::Visibility &vis)
 {
-  gcc_unreachable ();
-  return false;
+  if (vis.has_path ())
+    {
+      auto path = vis.get_path ();
+      ResolvePath::go (&path, parent);
+
+      // Do we need to lookup something here?
+      // Is it just about resolving the names correctly so we can look them up
+      // later?
+    }
+
+  return true;
 }
 
 // Default visitors implementations
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc
index 954669818de..2c383c927fa 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -238,6 +238,8 @@ ResolveItem::visit (AST::Module &module)
   mappings->insert_canonical_path (mappings->get_current_crate (),
 				   module.get_node_id (), cpath);
 
+  resolve_visibility (module.get_visibility ());
+
   NodeId scope_node_id = module.get_node_id ();
   resolver->get_name_scope ().push (scope_node_id);
   resolver->get_type_scope ().push (scope_node_id);
@@ -267,6 +269,8 @@ ResolveItem::visit (AST::TupleStruct &struct_decl)
   mappings->insert_canonical_path (mappings->get_current_crate (),
 				   struct_decl.get_node_id (), cpath);
 
+  resolve_visibility (struct_decl.get_visibility ());
+
   NodeId scope_node_id = struct_decl.get_node_id ();
   resolver->get_type_scope ().push (scope_node_id);
 
@@ -286,6 +290,8 @@ ResolveItem::visit (AST::TupleStruct &struct_decl)
       if (field.get_field_type ()->is_marked_for_strip ())
 	continue;
 
+      resolve_visibility (field.get_visibility ());
+
       ResolveType::go (field.get_field_type ().get (),
 		       struct_decl.get_node_id ());
     }
@@ -303,6 +309,8 @@ ResolveItem::visit (AST::Enum &enum_decl)
   mappings->insert_canonical_path (mappings->get_current_crate (),
 				   enum_decl.get_node_id (), cpath);
 
+  resolve_visibility (enum_decl.get_visibility ());
+
   NodeId scope_node_id = enum_decl.get_node_id ();
   resolver->get_type_scope ().push (scope_node_id);
 
@@ -328,6 +336,9 @@ ResolveItem::visit (AST::Enum &enum_decl)
 void
 ResolveItem::visit (AST::EnumItem &item)
 {
+  // Since at this point we cannot have visibilities on enum items anymore, we
+  // can skip handling them
+
   auto decl
     = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ());
   auto path = prefix.append (decl);
@@ -396,6 +407,8 @@ ResolveItem::visit (AST::StructStruct &struct_decl)
   mappings->insert_canonical_path (mappings->get_current_crate (),
 				   struct_decl.get_node_id (), cpath);
 
+  resolve_visibility (struct_decl.get_visibility ());
+
   NodeId scope_node_id = struct_decl.get_node_id ();
   resolver->get_type_scope ().push (scope_node_id);
 
@@ -415,6 +428,8 @@ ResolveItem::visit (AST::StructStruct &struct_decl)
       if (field.get_field_type ()->is_marked_for_strip ())
 	continue;
 
+      resolve_visibility (field.get_visibility ());
+
       ResolveType::go (field.get_field_type ().get (),
 		       struct_decl.get_node_id ());
     }
@@ -432,6 +447,8 @@ ResolveItem::visit (AST::Union &union_decl)
   mappings->insert_canonical_path (mappings->get_current_crate (),
 				   union_decl.get_node_id (), cpath);
 
+  resolve_visibility (union_decl.get_visibility ());
+
   NodeId scope_node_id = union_decl.get_node_id ();
   resolver->get_type_scope ().push (scope_node_id);
 
@@ -485,6 +502,8 @@ ResolveItem::visit (AST::ConstantItem &constant)
   mappings->insert_canonical_path (mappings->get_current_crate (),
 				   constant.get_node_id (), cpath);
 
+  resolve_visibility (constant.get_visibility ());
+
   ResolveType::go (constant.get_type ().get (), constant.get_node_id ());
   ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id (), path,
 		   cpath);
@@ -505,6 +524,8 @@ ResolveItem::visit (AST::Function &function)
   mappings->insert_canonical_path (mappings->get_current_crate (),
 				   function.get_node_id (), cpath);
 
+  resolve_visibility (function.get_visibility ());
+
   NodeId scope_node_id = function.get_node_id ();
   resolver->get_name_scope ().push (scope_node_id);
   resolver->get_type_scope ().push (scope_node_id);
@@ -559,6 +580,8 @@ ResolveItem::visit (AST::InherentImpl &impl_block)
   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
   resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
 
+  resolve_visibility (impl_block.get_visibility ());
+
   if (impl_block.has_generics ())
     {
       for (auto &generic : impl_block.get_generic_params ())
@@ -640,6 +663,9 @@ ResolveItem::visit (AST::Method &method)
 				   method.get_node_id (), cpath);
 
   NodeId scope_node_id = method.get_node_id ();
+
+  resolve_visibility (method.get_visibility ());
+
   resolver->get_name_scope ().push (scope_node_id);
   resolver->get_type_scope ().push (scope_node_id);
   resolver->get_label_scope ().push (scope_node_id);
@@ -711,6 +737,9 @@ void
 ResolveItem::visit (AST::TraitImpl &impl_block)
 {
   NodeId scope_node_id = impl_block.get_node_id ();
+
+  resolve_visibility (impl_block.get_visibility ());
+
   resolver->get_name_scope ().push (scope_node_id);
   resolver->get_type_scope ().push (scope_node_id);
   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
@@ -812,6 +841,9 @@ void
 ResolveItem::visit (AST::Trait &trait)
 {
   NodeId scope_node_id = trait.get_node_id ();
+
+  resolve_visibility (trait.get_visibility ());
+
   resolver->get_name_scope ().push (scope_node_id);
   resolver->get_type_scope ().push (scope_node_id);
   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
@@ -862,6 +894,8 @@ ResolveItem::visit (AST::Trait &trait)
 void
 ResolveItem::visit (AST::ExternBlock &extern_block)
 {
+  resolve_visibility (extern_block.get_visibility ());
+
   for (auto &item : extern_block.get_extern_items ())
     {
       resolve_extern_item (item.get ());
@@ -895,6 +929,8 @@ ResolveImplItems::visit (AST::TypeAlias &alias)
 {
   ResolveItem::visit (alias);
 
+  resolve_visibility (alias.get_visibility ());
+
   // FIXME this stops the erronious unused decls which will be fixed later on
   resolver->get_type_scope ().append_reference_for_def (alias.get_node_id (),
 							alias.get_node_id ());
@@ -911,6 +947,9 @@ void
 ResolveExternItem::visit (AST::ExternalFunctionItem &function)
 {
   NodeId scope_node_id = function.get_node_id ();
+
+  resolve_visibility (function.get_visibility ());
+
   resolver->get_name_scope ().push (scope_node_id);
   resolver->get_type_scope ().push (scope_node_id);
   resolver->get_label_scope ().push (scope_node_id);
@@ -945,6 +984,8 @@ ResolveExternItem::visit (AST::ExternalFunctionItem &function)
 void
 ResolveExternItem::visit (AST::ExternalStaticItem &item)
 {
+  resolve_visibility (item.get_visibility ());
+
   ResolveType::go (item.get_type ().get (), item.get_node_id ());
 }
 
diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc b/gcc/rust/resolve/rust-ast-resolve-path.cc
index 3e4bb3352de..c7597a25070 100644
--- a/gcc/rust/resolve/rust-ast-resolve-path.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-path.cc
@@ -279,90 +279,69 @@ ResolvePath::resolve_segments (CanonicalPath prefix, size_t offs,
     }
 }
 
-void
-ResolvePath::resolve_path (AST::SimplePath *expr)
+static bool
+lookup_and_insert_segment (Resolver *resolver, CanonicalPath path,
+			   NodeId segment_id, NodeId *to_resolve, bool &is_type)
 {
-  // resolve root segment first then apply segments in turn
-  auto &segs = expr->get_segments ();
-  auto &root_segment = segs.at (0);
-  auto &root_ident_seg = root_segment.get_segment_name ();
-
-  /**
-   * TODO: We need to handle functions and types later on for `use` statements.
-   * So we will also need to check the type scope
-   *
-   * bool segment_is_type = false;
-   * bool segment_is_func = false;
-   */
-  CanonicalPath root_seg_path
-    = CanonicalPath::new_seg (root_segment.get_node_id (), root_ident_seg);
-
-  // name scope first
-  if (resolver->get_name_scope ().lookup (root_seg_path, &resolved_node))
+  if (resolver->get_name_scope ().lookup (path, to_resolve))
     {
-      resolver->insert_resolved_name (root_segment.get_node_id (),
-				      resolved_node);
-      resolver->insert_new_definition (root_segment.get_node_id (),
-				       Definition{expr->get_node_id (),
-						  parent});
+      resolver->insert_resolved_name (segment_id, *to_resolve);
     }
-  else
+  else if (resolver->get_type_scope ().lookup (path, to_resolve))
     {
-      rust_error_at (expr->get_locus (),
-		     "Cannot find path %<%s%> in this scope",
-		     root_segment.as_string ().c_str ());
-      return;
+      is_type = true;
+      resolver->insert_resolved_type (segment_id, *to_resolve);
     }
-
-  bool is_single_segment = segs.size () == 1;
-  if (is_single_segment)
+  else
     {
-      // if (segment_is_type)
-      // resolver->insert_resolved_type (expr->get_node_id (), resolved_node);
-
-      resolver->insert_resolved_name (expr->get_node_id (), resolved_node);
-      resolver->insert_new_definition (expr->get_node_id (),
-				       Definition{expr->get_node_id (),
-						  parent});
-      return;
+      return false;
     }
 
-  resolve_simple_path_segments (root_seg_path, 1, expr->get_segments (),
-				expr->get_node_id (), expr->get_locus ());
+  return true;
 }
 
 void
-ResolvePath::resolve_simple_path_segments (
-  CanonicalPath prefix, size_t offs,
-  const std::vector<AST::SimplePathSegment> &segs, NodeId expr_node_id,
-  Location expr_locus)
+ResolvePath::resolve_path (AST::SimplePath *simple_path)
 {
-  /**
-   * TODO: We also need to handle types and functions here
-   */
+  // resolve root segment first then apply segments in turn
+  auto expr_node_id = simple_path->get_node_id ();
+  auto is_type = false;
 
-  CanonicalPath path = prefix;
-  for (const auto &seg : segs)
+  auto path = CanonicalPath::create_empty ();
+  for (const auto &seg : simple_path->get_segments ())
     {
       auto s = ResolveSimplePathSegmentToCanonicalPath::resolve (seg);
       path = path.append (s);
 
+      // Reset state
       resolved_node = UNKNOWN_NODEID;
+      is_type = false;
 
-      if (resolver->get_name_scope ().lookup (path, &resolved_node))
+      if (!lookup_and_insert_segment (resolver, path, seg.get_node_id (),
+				      &resolved_node, is_type))
 	{
-	  resolver->insert_resolved_name (seg.get_node_id (), resolved_node);
-	  resolver->insert_new_definition (seg.get_node_id (),
-					   Definition{expr_node_id, parent});
+	  rust_error_at (seg.get_locus (),
+			 "cannot find simple path segment %qs",
+			 seg.as_string ().c_str ());
+	  return;
 	}
     }
 
-  if (resolved_node != UNKNOWN_NODEID)
+  if (resolved_node == UNKNOWN_NODEID)
     {
-      resolver->insert_resolved_name (expr_node_id, resolved_node);
-      resolver->insert_new_definition (expr_node_id,
-				       Definition{expr_node_id, parent});
+      rust_error_at (simple_path->get_locus (),
+		     "could not resolve simple path %qs",
+		     simple_path->as_string ().c_str ());
+      return;
     }
+
+  if (is_type)
+    resolver->insert_resolved_type (expr_node_id, resolved_node);
+  else
+    resolver->insert_resolved_name (expr_node_id, resolved_node);
+
+  resolver->insert_new_definition (expr_node_id,
+				   Definition{expr_node_id, parent});
 }
 
 } // namespace Resolver
diff --git a/gcc/testsuite/rust/compile/pub_restricted_1.rs b/gcc/testsuite/rust/compile/pub_restricted_1.rs
new file mode 100644
index 00000000000..01fb65ea610
--- /dev/null
+++ b/gcc/testsuite/rust/compile/pub_restricted_1.rs
@@ -0,0 +1,14 @@
+pub mod foo {
+    pub mod bar {
+        pub fn baz() {}
+    }
+}
+
+// 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." }
+
+fn main() {}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-08 12:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 12:40 [gcc/devel/rust/master] ast: resolve: Implement `resolve_visibility` method Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).