[COMMITTED 25/77] gccrs: Handle ribs in GlobbingVisitor

[email protected]
Newsgroups gmane.comp.gcc.rust,gmane.comp.gcc.patches
Message-ID <[email protected]>
From: Owen Avery <[email protected]>

GlobbingVisitor can copy definitions between ribs, instead of creating
new definitions from the AST.

gcc/rust/ChangeLog:

	* resolve/rust-finalize-imports-2.0.cc (GlobbingVisitor::go):
	Use visit_container.
	(GlobbingVisitor::visit_crate_container)
	(GlobbingVisitor::visit_module_container)
	(GlobbingVisitor::visit_enum_container, GlobbingVisitor::visit):
	Remove member functions.
	(GlobbingVisitor::visit_container)
	(GlobbingVisitor::glob_definitions)
	(GlobbingVisitor::glob_definition): New member functions.
	* resolve/rust-finalize-imports-2.0.h (class GlobbingVisitor):
	Remove DefaultASTVisitor as base class.
	(GlobbingVisitor::visit_crate_container)
	(GlobbingVisitor::visit_module_container)
	(GlobbingVisitor::visit_enum_container, GlobbingVisitor::visit):
	Remove member functions.
	(GlobbingVisitor::visit_container)
	(GlobbingVisitor::glob_definitions)
	(GlobbingVisitor::glob_definition): New member functions.

gcc/testsuite/ChangeLog:

	* rust/compile/glob-import-import.rs: New test.

Signed-off-by: Owen Avery <[email protected]>
---
 gcc/rust/resolve/rust-finalize-imports-2.0.cc | 147 ++++--------------
 gcc/rust/resolve/rust-finalize-imports-2.0.h  |  30 +---
 .../rust/compile/glob-import-import.rs        |  19 +++
 3 files changed, 61 insertions(+), 135 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/glob-import-import.rs

diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.cc b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
index 8ad9322bbd7..3dcaa42903e 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.cc
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
@@ -33,145 +33,66 @@ GlobbingVisitor::go (AST::GlobContainer *container)
   switch (container->get_glob_container_kind ())
     {
     case AST::GlobContainer::Kind::Module:
-      visit_module_container (static_cast<AST::Module &> (*container));
+      visit_container (static_cast<AST::Module &> (*container).get_node_id ());
       break;
     case AST::GlobContainer::Kind::Crate:
-      visit_crate_container (static_cast<AST::Crate &> (*container));
+      visit_container (static_cast<AST::Crate &> (*container).get_node_id ());
       break;
     case AST::GlobContainer::Kind::Enum:
-      visit_enum_container (static_cast<AST::Enum &> (*container));
+      visit_container (static_cast<AST::Enum &> (*container).get_node_id ());
       break;
     default:
       rust_unreachable ();
     }
 }
 
+template <typename T>
 void
-GlobbingVisitor::visit_crate_container (AST::Crate &crate)
+GlobbingVisitor::visit_container (T &stack, NodeId nodeid)
 {
-  for (auto &i : crate.items)
-    visit (i);
+  auto rib = stack.dfs_rib (stack.root, nodeid);
+  if (rib.has_value ())
+    glob_definitions (stack.peek (), rib.value ());
 }
 
 void
-GlobbingVisitor::visit_module_container (AST::Module &module)
+GlobbingVisitor::visit_container (NodeId nodeid)
 {
-  for (auto &i : module.get_items ())
-    visit (i);
+  visit_container (ctx.values, nodeid);
+  visit_container (ctx.types, nodeid);
+  visit_container (ctx.macros, nodeid);
+  visit_container (ctx.labels, nodeid);
 }
 
 void
-GlobbingVisitor::visit_enum_container (AST::Enum &item)
+GlobbingVisitor::glob_definitions (Rib &dst, Rib &src)
 {
-  for (auto &variant : item.get_variants ())
+  for (auto &ent : src.get_values ())
     {
-      ctx.insert_globbed (variant->get_identifier (), variant->get_node_id (),
-			  Namespace::Types);
-      if (variant->get_enum_item_kind () != AST::EnumItem::Kind::Struct)
-	ctx.insert_globbed (variant->get_identifier (), variant->get_node_id (),
-			    Namespace::Values);
+      auto globbed = glob_definition (ent.second);
+      if (globbed.has_value ())
+	{
+	  auto res = dst.insert (ent.first, globbed.value ());
+	  // inserting a globbed definition should (?) always succeed
+	  // TODO: double check
+	  // TODO: mark fixed point as dirty/changed?
+	  rust_assert (res.has_value ()
+		       || res.error ().existing
+			    == globbed.value ().get_node_id ());
+	}
     }
 }
 
-void
-GlobbingVisitor::visit (AST::Module &module)
-{
-  ctx.insert_globbed (module.get_name (), module.get_node_id (),
-		      Namespace::Types);
-}
-
-void
-GlobbingVisitor::visit (AST::MacroRulesDefinition &macro)
-{
-  ctx.insert_globbed (macro.get_rule_name (), macro.get_node_id (),
-		      Namespace::Macros);
-}
-
-void
-GlobbingVisitor::visit (AST::Function &function)
+tl::optional<Rib::Definition>
+GlobbingVisitor::glob_definition (const Rib::Definition &def)
 {
-  ctx.insert_globbed (function.get_function_name (), function.get_node_id (),
-		      Namespace::Values);
-}
-
-void
-GlobbingVisitor::visit (AST::StaticItem &static_item)
-{
-  ctx.insert_globbed (static_item.get_identifier (), static_item.get_node_id (),
-		      Namespace::Values);
-}
-
-void
-GlobbingVisitor::visit (AST::StructStruct &struct_item)
-{
-  ctx.insert_globbed (struct_item.get_identifier (), struct_item.get_node_id (),
-		      Namespace::Types);
-  if (struct_item.is_unit_struct ())
-    ctx.insert_globbed (struct_item.get_identifier (),
-			struct_item.get_node_id (), Namespace::Values);
-}
-
-void
-GlobbingVisitor::visit (AST::TupleStruct &tuple_struct)
-{
-  ctx.insert_globbed (tuple_struct.get_identifier (),
-		      tuple_struct.get_node_id (), Namespace::Types);
-
-  ctx.insert_globbed (tuple_struct.get_identifier (),
-		      tuple_struct.get_node_id (), Namespace::Values);
-}
-
-void
-GlobbingVisitor::visit (AST::Enum &enum_item)
-{
-  ctx.insert_globbed (enum_item.get_identifier (), enum_item.get_node_id (),
-		      Namespace::Types);
-}
-
-void
-GlobbingVisitor::visit (AST::Union &union_item)
-{
-  ctx.insert_globbed (union_item.get_identifier (), union_item.get_node_id (),
-		      Namespace::Values);
-}
-
-void
-GlobbingVisitor::visit (AST::ConstantItem &const_item)
-{
-  ctx.insert_globbed (const_item.get_identifier (), const_item.get_node_id (),
-		      Namespace::Values);
-}
-
-void
-GlobbingVisitor::visit (AST::TypeAlias &type)
-{
-  ctx.insert_globbed (type.get_new_type_name (), type.get_node_id (),
-		      Namespace::Types);
-}
-
-void
-GlobbingVisitor::visit (AST::Trait &trait)
-{
-  ctx.insert_globbed (trait.get_identifier (), trait.get_node_id (),
-		      Namespace::Types);
-}
-
-void
-GlobbingVisitor::visit (AST::InherentImpl &impl)
-{}
-
-void
-GlobbingVisitor::visit (AST::TraitImpl &impl)
-{}
-
-void
-GlobbingVisitor::visit (AST::ExternCrate &crate)
-{}
+  if (def.is_ambiguous ())
+    {
+      // TODO: error?
+      return tl::nullopt;
+    }
 
-void
-GlobbingVisitor::visit (AST::UseDeclaration &use)
-{
-  // Handle cycles ?
+  return Rib::Definition::Globbed (def.get_node_id ());
 }
 
 } // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.h b/gcc/rust/resolve/rust-finalize-imports-2.0.h
index 3a1e7026667..281c979ba3e 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.h
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.h
@@ -26,34 +26,20 @@
 namespace Rust {
 namespace Resolver2_0 {
 
-class GlobbingVisitor : public AST::DefaultASTVisitor
+class GlobbingVisitor
 {
-  using AST::DefaultASTVisitor::visit;
-
 public:
   GlobbingVisitor (NameResolutionContext &ctx) : ctx (ctx) {}
 
   void go (AST::GlobContainer *container);
 
-  void visit_crate_container (AST::Crate &crate);
-  void visit_module_container (AST::Module &module);
-  void visit_enum_container (AST::Enum &item);
-
-  void visit (AST::Module &module) override;
-  void visit (AST::MacroRulesDefinition &macro) override;
-  void visit (AST::Function &function) override;
-  void visit (AST::StaticItem &static_item) override;
-  void visit (AST::StructStruct &struct_item) override;
-  void visit (AST::TupleStruct &tuple_struct) override;
-  void visit (AST::Enum &enum_item) override;
-  void visit (AST::Union &union_item) override;
-  void visit (AST::ConstantItem &const_item) override;
-  void visit (AST::TypeAlias &type) override;
-  void visit (AST::Trait &trait) override;
-  void visit (AST::InherentImpl &impl) override;
-  void visit (AST::TraitImpl &impl) override;
-  void visit (AST::ExternCrate &crate) override;
-  void visit (AST::UseDeclaration &use) override;
+  template <typename T> void visit_container (T &stack, NodeId nodeid);
+
+  void visit_container (NodeId nodeid);
+
+  void glob_definitions (Rib &dst, Rib &src);
+
+  tl::optional<Rib::Definition> glob_definition (const Rib::Definition &def);
 
 private:
   NameResolutionContext &ctx;
diff --git a/gcc/testsuite/rust/compile/glob-import-import.rs b/gcc/testsuite/rust/compile/glob-import-import.rs
new file mode 100644
index 00000000000..e3f5c6de88e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/glob-import-import.rs
@@ -0,0 +1,19 @@
+// { dg-additional-options "-w" }
+// TODO: this shouldn't warn
+
+#![feature(no_core)]
+#![no_core]
+
+pub mod foo {
+    pub struct S;
+}
+
+use foo::S;
+
+mod bar {
+    use super::*;
+
+    pub const X: S = S;
+}
+
+pub const Y: S = bar::X;
-- 
2.50.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.