From: Arthur Cohen <arthur.co...@embecosm.com>

gcc/rust/ChangeLog:

        * Make-lang.in: Add new object file.
        * ast/rust-item.h: Constify method.
        * resolve/rust-early-name-resolver-2.0.cc (Early::go): Call into
        the imports finalizer.
        (Early::resolve_glob_import): Remove old resolution.
        (Early::resolve_rebind_import): Likewise.
        * resolve/rust-toplevel-name-resolver-2.0.cc (GlobbingVisitor::go):
        New function.
        (GlobbingVisitor::visit): Likewise.
        (TopLevel::visit): Do not call into handle_use_* functions anymore.
        * resolve/rust-toplevel-name-resolver-2.0.h (class GlobbingVisitor):
        New.
        * resolve/rust-finalize-imports-2.0.cc: New file.
        * resolve/rust-finalize-imports-2.0.h: New file.
---
 gcc/rust/Make-lang.in                         |   1 +
 gcc/rust/ast/rust-item.h                      |   2 +-
 .../resolve/rust-early-name-resolver-2.0.cc   |  31 +--
 gcc/rust/resolve/rust-finalize-imports-2.0.cc | 206 ++++++++++++++++++
 gcc/rust/resolve/rust-finalize-imports-2.0.h  |  96 ++++++++
 .../rust-toplevel-name-resolver-2.0.cc        | 112 ----------
 .../resolve/rust-toplevel-name-resolver-2.0.h |  25 +--
 7 files changed, 309 insertions(+), 164 deletions(-)
 create mode 100644 gcc/rust/resolve/rust-finalize-imports-2.0.cc
 create mode 100644 gcc/rust/resolve/rust-finalize-imports-2.0.h

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 950cd3af073..c1a3c1fe9f3 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -131,6 +131,7 @@ GRS_OBJS = \
     rust/rust-default-resolver.o \
     rust/rust-toplevel-name-resolver-2.0.o \
     rust/rust-early-name-resolver-2.0.o \
+       rust/rust-finalize-imports-2.0.o \
     rust/rust-late-name-resolver-2.0.o \
        rust/rust-immutable-name-resolution-context.o \
     rust/rust-early-name-resolver.o \
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index bd9113ffa23..2ae7c44398b 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -1213,7 +1213,7 @@ public:
 
   std::string as_string () const override;
 
-  NewBindType get_new_bind_type () { return bind_type; }
+  NewBindType get_new_bind_type () const { return bind_type; }
 
   void accept_vis (ASTVisitor &vis) override;
 
diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index 884c05a93c3..41d0a075bbb 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -21,6 +21,7 @@
 #include "rust-diagnostics.h"
 #include "rust-toplevel-name-resolver-2.0.h"
 #include "rust-attributes.h"
+#include "rust-finalize-imports-2.0.h"
 
 namespace Rust {
 namespace Resolver2_0 {
@@ -57,6 +58,9 @@ Early::go (AST::Crate &crate)
   for (auto &&import : toplevel.get_imports_to_resolve ())
     build_import_mapping (std::move (import));
 
+  // Once this is done, we finalize their resolution
+  FinalizeImports::go (import_mappings, toplevel, ctx);
+
   // We now proceed with resolving macros, which can be nested in almost any
   // items
   textual_scope.push ();
@@ -81,10 +85,6 @@ Early::resolve_glob_import (TopLevel::ImportKind &&glob)
   // up the module proper in `FinalizeImports`
   import_mappings.insert ({std::move (glob), resolved->get_node_id ()});
 
-  // FIXME: This needs to be done in `FinalizeImports`
-  // GlobbingVisitor gvisitor (ctx);
-  // gvisitor.go (result.value ());
-
   return true;
 }
 
@@ -169,29 +169,6 @@ Early::resolve_rebind_import (TopLevel::ImportKind 
&&rebind_import)
 {
   auto &path = rebind_import.to_resolve;
 
-  // We can fetch the value here as `resolve_rebind` will only be called on
-  // imports of the right kind
-  auto &rebind = rebind_import.rebind.value ();
-
-  location_t locus = UNKNOWN_LOCATION;
-  std::string declared_name;
-
-  // FIXME: This needs to be done in `FinalizeImports`
-  switch (rebind.get_new_bind_type ())
-    {
-    case AST::UseTreeRebind::NewBindType::IDENTIFIER:
-      declared_name = rebind.get_identifier ().as_string ();
-      locus = rebind.get_identifier ().get_locus ();
-      break;
-    case AST::UseTreeRebind::NewBindType::NONE:
-      declared_name = path.get_final_segment ().as_string ();
-      locus = path.get_final_segment ().get_locus ();
-      break;
-    case AST::UseTreeRebind::NewBindType::WILDCARD:
-      rust_unreachable ();
-      break;
-    }
-
   return ctx.values.resolve_path (path.get_segments ())
     .or_else ([&] () { return ctx.types.resolve_path (path.get_segments ()); })
     .or_else ([&] () { return ctx.macros.resolve_path (path.get_segments ()); 
})
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.cc 
b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
new file mode 100644
index 00000000000..1725e71e17b
--- /dev/null
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
@@ -0,0 +1,206 @@
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-finalize-imports-2.0.h"
+#include "rust-hir-map.h"
+#include "rust-name-resolution-context.h"
+#include "rust-rib.h"
+#include "rust-toplevel-name-resolver-2.0.h"
+
+namespace Rust {
+namespace Resolver2_0 {
+
+void
+GlobbingVisitor::go (AST::Module *module)
+{
+  for (auto &i : module->get_items ())
+    visit (i);
+}
+
+void
+GlobbingVisitor::visit (AST::Module &module)
+{
+  if (module.get_visibility ().is_public ())
+    ctx.insert_shadowable (module.get_name (), module.get_node_id (),
+                          Namespace::Types);
+}
+
+void
+GlobbingVisitor::visit (AST::MacroRulesDefinition &macro)
+{
+  if (macro.get_visibility ().is_public ())
+    ctx.insert_shadowable (macro.get_rule_name (), macro.get_node_id (),
+                          Namespace::Macros);
+}
+
+void
+GlobbingVisitor::visit (AST::Function &function)
+{
+  if (function.get_visibility ().is_public ())
+    ctx.insert_shadowable (function.get_function_name (),
+                          function.get_node_id (), Namespace::Values);
+}
+
+void
+GlobbingVisitor::visit (AST::StaticItem &static_item)
+{
+  if (static_item.get_visibility ().is_public ())
+    ctx.insert_shadowable (static_item.get_identifier (),
+                          static_item.get_node_id (), Namespace::Values);
+}
+
+void
+GlobbingVisitor::visit (AST::StructStruct &struct_item)
+{
+  if (struct_item.get_visibility ().is_public ())
+    {
+      ctx.insert_shadowable (struct_item.get_identifier (),
+                            struct_item.get_node_id (), Namespace::Types);
+      if (struct_item.is_unit_struct ())
+       ctx.insert_shadowable (struct_item.get_identifier (),
+                              struct_item.get_node_id (), Namespace::Values);
+    }
+}
+
+void
+GlobbingVisitor::visit (AST::TupleStruct &tuple_struct)
+{
+  if (tuple_struct.get_visibility ().is_public ())
+    {
+      ctx.insert_shadowable (tuple_struct.get_identifier (),
+                            tuple_struct.get_node_id (), Namespace::Types);
+
+      ctx.insert_shadowable (tuple_struct.get_identifier (),
+                            tuple_struct.get_node_id (), Namespace::Values);
+    }
+}
+
+void
+GlobbingVisitor::visit (AST::Enum &enum_item)
+{
+  if (enum_item.get_visibility ().is_public ())
+    ctx.insert_shadowable (enum_item.get_identifier (),
+                          enum_item.get_node_id (), Namespace::Types);
+}
+
+void
+GlobbingVisitor::visit (AST::Union &union_item)
+{
+  if (union_item.get_visibility ().is_public ())
+    ctx.insert_shadowable (union_item.get_identifier (),
+                          union_item.get_node_id (), Namespace::Values);
+}
+
+void
+GlobbingVisitor::visit (AST::ConstantItem &const_item)
+{
+  if (const_item.get_visibility ().is_public ())
+    ctx.insert_shadowable (const_item.get_identifier (),
+                          const_item.get_node_id (), Namespace::Values);
+}
+
+void
+GlobbingVisitor::visit (AST::ExternCrate &crate)
+{}
+
+void
+GlobbingVisitor::visit (AST::UseDeclaration &use)
+{
+  // Handle cycles ?
+}
+
+void
+finalize_simple_import (TopLevel &toplevel,
+                       const std::pair<TopLevel::ImportKind, NodeId> &mapping)
+{
+  // FIXME: We probably need to store namespace information
+
+  auto locus = mapping.first.to_resolve.get_locus ();
+  auto def = mapping.second;
+  auto identifier
+    = mapping.first.to_resolve.get_final_segment ().get_segment_name ();
+
+  // FIXME: Fix the namespace in which we insert the new definition
+  toplevel.insert_or_error_out (identifier, locus, def, Namespace::Values);
+}
+
+void
+finalize_glob_import (NameResolutionContext &ctx,
+                     const std::pair<TopLevel::ImportKind, NodeId> &mapping)
+{
+  auto module = Analysis::Mappings::get ().lookup_ast_module (mapping.second);
+  rust_assert (module);
+
+  GlobbingVisitor glob_visitor (ctx);
+  glob_visitor.go (module.value ());
+}
+
+void
+finalize_rebind_import (TopLevel &toplevel,
+                       const std::pair<TopLevel::ImportKind, NodeId> &mapping)
+{
+  // We can fetch the value here as `resolve_rebind` will only be called on
+  // imports of the right kind
+  auto &path = mapping.first.to_resolve;
+  auto &rebind = mapping.first.rebind.value ();
+  auto def = mapping.second;
+
+  location_t locus = UNKNOWN_LOCATION;
+  std::string declared_name;
+
+  // FIXME: This needs to be done in `FinalizeImports`
+  switch (rebind.get_new_bind_type ())
+    {
+    case AST::UseTreeRebind::NewBindType::IDENTIFIER:
+      declared_name = rebind.get_identifier ().as_string ();
+      locus = rebind.get_identifier ().get_locus ();
+      break;
+    case AST::UseTreeRebind::NewBindType::NONE:
+      declared_name = path.get_final_segment ().as_string ();
+      locus = path.get_final_segment ().get_locus ();
+      break;
+    case AST::UseTreeRebind::NewBindType::WILDCARD:
+      rust_unreachable ();
+      break;
+    }
+
+  // FIXME: Fix the namespace in which we insert the new definition
+  toplevel.insert_or_error_out (declared_name, locus, def, Namespace::Values);
+}
+
+void
+FinalizeImports::go (std::map<TopLevel::ImportKind, NodeId> import_mappings,
+                    TopLevel &toplevel, NameResolutionContext &ctx)
+{
+  for (const auto &mapping : import_mappings)
+    switch (mapping.first.kind)
+      {
+      case TopLevel::ImportKind::Kind::Glob:
+       finalize_glob_import (ctx, mapping);
+       break;
+      case TopLevel::ImportKind::Kind::Simple:
+       finalize_simple_import (toplevel, mapping);
+       break;
+      case TopLevel::ImportKind::Kind::Rebind:
+       finalize_rebind_import (toplevel, mapping);
+       break;
+      }
+}
+
+} // namespace Resolver2_0
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.h 
b/gcc/rust/resolve/rust-finalize-imports-2.0.h
new file mode 100644
index 00000000000..e566a485275
--- /dev/null
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.h
@@ -0,0 +1,96 @@
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-name-resolution-context.h"
+#include "rust-toplevel-name-resolver-2.0.h"
+
+namespace Rust {
+namespace Resolver2_0 {
+
+class GlobbingVisitor : public AST::DefaultASTVisitor
+{
+  using AST::DefaultASTVisitor::visit;
+
+public:
+  GlobbingVisitor (NameResolutionContext &ctx) : ctx (ctx) {}
+
+  void go (AST::Module *module);
+  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::ExternCrate &crate) override;
+  void visit (AST::UseDeclaration &use) override;
+
+private:
+  NameResolutionContext &ctx;
+};
+
+// TODO: Fix documentation
+// How do we do that?
+//
+// We want to resolve in the EarlyNameResolver, but we want to declare in the
+// TopLevel Should the TopLevel declare stubs? How does rustc do it? How to do
+// that for globbing? Should we do globbing afterwards once we've declared all
+// the Uses*?
+//
+// Basically, for each use declare it in a separate map - in the
+// EarlyNameResolver resolve and fix the ForeverStack? Emptying the maps each
+// time?
+//
+// e.g. TopLevel builds a std::vector<NodeId, SimplePath> use_trees_to_resolve;
+// Early goes through and resolves the SimplePath, then replaces the NodeId 
with
+// the resolved one? Do we even need to do that?
+//
+// rustc just creates an empty definition for the use tree.
+//
+// What about globbing? std::vector<GlobbulesPath> globules;
+// Early goes through and visits the module's path and calls the
+// GlobbingVisitor?
+//
+// the file `imports.rs` goes through and *finalizes* imports. So we can
+// probably add a FinalizeImport pass after the TopLevel and the Early.
+// - TopLevel takes care of declaring these use trees
+// - Early takes care of resolving them to definition points
+// - Finalize takes care of mapping the use's definition point to the actual
+// definition point
+//     - We need to work more on that last bit to know exactly what is being
+// inserted, but probably it's going to mutate the ForeverStack - is that okay?
+//     - Oh actually maybe no!
+//     - TopLevel creates a map of UseTrees with paths to resolve. This should
+// probably be an ImportKind enum or whatever
+//     - Early resolves them, creates a map of SimplePath with the associated
+// definition: Map<ImportKind, ImportData>
+//     - Finalizes visits all UseTrees and inserts the Definitions found for
+// each ImportKind - easy!
+//     - yay!
+
+class FinalizeImports
+{
+public:
+  static void go (std::map<TopLevel::ImportKind, NodeId> import_mappings,
+                 TopLevel &toplevel, NameResolutionContext &ctx);
+};
+
+} // namespace Resolver2_0
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 8a1d8be0694..b6695f6de7c 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -26,105 +26,6 @@
 namespace Rust {
 namespace Resolver2_0 {
 
-void
-GlobbingVisitor::go (AST::Module *module)
-{
-  for (auto &i : module->get_items ())
-    visit (i);
-}
-
-void
-GlobbingVisitor::visit (AST::Module &module)
-{
-  if (module.get_visibility ().is_public ())
-    ctx.insert_shadowable (module.get_name (), module.get_node_id (),
-                          Namespace::Types);
-}
-
-void
-GlobbingVisitor::visit (AST::MacroRulesDefinition &macro)
-{
-  if (macro.get_visibility ().is_public ())
-    ctx.insert_shadowable (macro.get_rule_name (), macro.get_node_id (),
-                          Namespace::Macros);
-}
-
-void
-GlobbingVisitor::visit (AST::Function &function)
-{
-  if (function.get_visibility ().is_public ())
-    ctx.insert_shadowable (function.get_function_name (),
-                          function.get_node_id (), Namespace::Values);
-}
-
-void
-GlobbingVisitor::visit (AST::StaticItem &static_item)
-{
-  if (static_item.get_visibility ().is_public ())
-    ctx.insert_shadowable (static_item.get_identifier (),
-                          static_item.get_node_id (), Namespace::Values);
-}
-
-void
-GlobbingVisitor::visit (AST::StructStruct &struct_item)
-{
-  if (struct_item.get_visibility ().is_public ())
-    {
-      ctx.insert_shadowable (struct_item.get_identifier (),
-                            struct_item.get_node_id (), Namespace::Types);
-      if (struct_item.is_unit_struct ())
-       ctx.insert_shadowable (struct_item.get_identifier (),
-                              struct_item.get_node_id (), Namespace::Values);
-    }
-}
-
-void
-GlobbingVisitor::visit (AST::TupleStruct &tuple_struct)
-{
-  if (tuple_struct.get_visibility ().is_public ())
-    {
-      ctx.insert_shadowable (tuple_struct.get_identifier (),
-                            tuple_struct.get_node_id (), Namespace::Types);
-
-      ctx.insert_shadowable (tuple_struct.get_identifier (),
-                            tuple_struct.get_node_id (), Namespace::Values);
-    }
-}
-
-void
-GlobbingVisitor::visit (AST::Enum &enum_item)
-{
-  if (enum_item.get_visibility ().is_public ())
-    ctx.insert_shadowable (enum_item.get_identifier (),
-                          enum_item.get_node_id (), Namespace::Types);
-}
-
-void
-GlobbingVisitor::visit (AST::Union &union_item)
-{
-  if (union_item.get_visibility ().is_public ())
-    ctx.insert_shadowable (union_item.get_identifier (),
-                          union_item.get_node_id (), Namespace::Values);
-}
-
-void
-GlobbingVisitor::visit (AST::ConstantItem &const_item)
-{
-  if (const_item.get_visibility ().is_public ())
-    ctx.insert_shadowable (const_item.get_identifier (),
-                          const_item.get_node_id (), Namespace::Values);
-}
-
-void
-GlobbingVisitor::visit (AST::ExternCrate &crate)
-{}
-
-void
-GlobbingVisitor::visit (AST::UseDeclaration &use)
-{
-  // Handle cycles ?
-}
-
 TopLevel::TopLevel (NameResolutionContext &resolver)
   : DefaultResolver (resolver)
 {}
@@ -564,25 +465,12 @@ TopLevel::visit (AST::UseDeclaration &use)
   for (auto &&path : paths)
     imports_to_resolve.emplace_back (ImportKind::Simple (std::move (path)));
 
-  // if (!handle_use_dec (path))
-  //   rust_error_at (path.get_final_segment ().get_locus (), ErrorCode::E0433,
-  //    "unresolved import %qs", path.as_string ().c_str ());
-
   for (auto &&glob : glob_path)
     imports_to_resolve.emplace_back (ImportKind::Glob (std::move (glob)));
 
-  // if (!handle_use_glob (glob))
-  //   rust_error_at (glob.get_final_segment ().get_locus (), ErrorCode::E0433,
-  //    "unresolved import %qs", glob.as_string ().c_str ());
-
   for (auto &&rebind : rebind_path)
     imports_to_resolve.emplace_back (
       ImportKind::Rebind (std::move (rebind.first), std::move 
(rebind.second)));
-
-  // if (!handle_rebind (rebind))
-  //   rust_error_at (rebind.first.get_final_segment ().get_locus (),
-  //    ErrorCode::E0433, "unresolved import %qs",
-  //    rebind.first.as_string ().c_str ());
 }
 
 } // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
index 77dd522c17c..7b505cb6ace 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -29,29 +29,6 @@
 namespace Rust {
 namespace Resolver2_0 {
 
-class GlobbingVisitor : public AST::DefaultASTVisitor
-{
-  using AST::DefaultASTVisitor::visit;
-
-public:
-  GlobbingVisitor (NameResolutionContext &ctx) : ctx (ctx) {}
-
-  void go (AST::Module *module);
-  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::ExternCrate &crate) override;
-  void visit (AST::UseDeclaration &use) override;
-
-private:
-  NameResolutionContext &ctx;
-};
 /**
  * The `TopLevel` visitor takes care of collecting all the definitions in a
  * crate, and inserting them into the proper namespaces. These definitions can
@@ -123,7 +100,6 @@ public:
     return std::move (imports_to_resolve);
   }
 
-private:
   /**
    * Insert a new definition or error out if a definition with the same name 
was
    * already present in the same namespace in the same scope.
@@ -140,6 +116,7 @@ private:
                            const location_t &locus, const NodeId &id,
                            Namespace ns);
 
+private:
   // FIXME: Do we move these to our mappings?
   std::unordered_map<NodeId, location_t> node_locations;
 
-- 
2.45.2

Reply via email to