https://gcc.gnu.org/g:9047b32383a05b5ef5909de5eed35a0cd3c9a76a

commit r15-8395-g9047b32383a05b5ef5909de5eed35a0cd3c9a76a
Author: Arthur Cohen <arthur.co...@embecosm.com>
Date:   Sat Apr 6 23:02:51 2024 +0200

    gccrs: imports: Make FinalizeImports a resolver visitor as well
    
    gcc/rust/ChangeLog:
    
            * resolve/rust-finalize-imports-2.0.cc (FinalizeImports::go): Turn
            static method into method.
            (FinalizeImports::visit): New.
            * resolve/rust-finalize-imports-2.0.h (class FinalizeImports): Make
            FinalizeImports a visitor.
            * resolve/rust-early-name-resolver-2.0.cc (Early::go): Use new 
FinalizeImports API.
            (Early::resolve_glob_import): Use new API.
            (Early::resolve_simple_import): Likewise.
            (Early::resolve_rebind_import): Likewise.
            (Early::build_import_mapping): Likewise.
            * resolve/rust-early-name-resolver-2.0.h: Likewise.
            * resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): 
Likewise.
            * resolve/rust-toplevel-name-resolver-2.0.h: Likewise.

Diff:
---
 gcc/rust/resolve/rust-early-name-resolver-2.0.cc   | 84 ++++++++++++++--------
 gcc/rust/resolve/rust-early-name-resolver-2.0.h    | 14 ++--
 gcc/rust/resolve/rust-finalize-imports-2.0.cc      | 23 +++++-
 gcc/rust/resolve/rust-finalize-imports-2.0.h       | 23 ++++--
 .../resolve/rust-toplevel-name-resolver-2.0.cc     | 10 ++-
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h |  5 +-
 6 files changed, 114 insertions(+), 45 deletions(-)

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 ba73a54d412a..ac8eb940c8d5 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -59,7 +59,7 @@ Early::go (AST::Crate &crate)
     build_import_mapping (std::move (import));
 
   // Once this is done, we finalize their resolution
-  FinalizeImports::go (import_mappings, toplevel, ctx);
+  FinalizeImports (std::move (import_mappings), toplevel, ctx).go (crate);
 
   // We now proceed with resolving macros, which can be nested in almost any
   // items
@@ -70,7 +70,7 @@ Early::go (AST::Crate &crate)
 }
 
 bool
-Early::resolve_glob_import (TopLevel::ImportKind &&glob)
+Early::resolve_glob_import (NodeId use_dec_id, TopLevel::ImportKind &&glob)
 {
   auto resolved = ctx.types.resolve_path (glob.to_resolve.get_segments ());
   if (!resolved.has_value ())
@@ -84,58 +84,86 @@ Early::resolve_glob_import (TopLevel::ImportKind &&glob)
   // here, we insert the module's NodeId into the import_mappings and will look
   // up the module proper in `FinalizeImports`
   // The namespace does not matter here since we are dealing with a glob
-  import_mappings.insert ({std::move (glob), ImportData::Glob (*resolved)});
+  // TODO: Ugly
+  import_mappings.insert (
+    {use_dec_id, {{std::move (glob), ImportData::Glob (*resolved)}}});
 
   return true;
 }
 
 bool
-Early::resolve_simple_import (TopLevel::ImportKind &&import)
+Early::resolve_simple_import (NodeId use_dec_id, TopLevel::ImportKind &&import)
 {
   return ctx.resolve_path (import.to_resolve)
     .map ([&] (std::pair<Rib::Definition, Namespace> def_ns) {
-      import_mappings.insert (
-       {std::move (import), ImportData::Simple (def_ns)});
+      // We insert an empty vector, unless an element was already present for
+      // `use_dec_id` - which is returned in the tuple's first member
+      auto tuple = import_mappings.insert ({use_dec_id, {}});
+      // We then get that tuple's first member, which will be an iterator to 
the
+      // existing vec<pair<ImportKind, ImportData>> OR an iterator to our newly
+      // created empty vector (plus its key since this is a hashmap iterator).
+      // we then access the second member of the pair to get access to the
+      // vector directly.
+      auto &imports = tuple.first->second;
+
+      imports.emplace_back (
+       std::make_pair (std::move (import), ImportData::Simple (def_ns)));
     })
     .has_value ();
 }
 
 bool
-Early::resolve_rebind_import (TopLevel::ImportKind &&rebind_import)
+Early::resolve_rebind_import (NodeId use_dec_id,
+                             TopLevel::ImportKind &&rebind_import)
 {
   return ctx.resolve_path (rebind_import.to_resolve)
     .map ([&] (std::pair<Rib::Definition, Namespace> def_ns) {
-      import_mappings.insert (
-       {std::move (rebind_import), ImportData::Rebind (def_ns)});
+      // We insert an empty vector, unless an element was already present for
+      // `use_dec_id` - which is returned in the tuple's first member
+      auto tuple = import_mappings.insert ({use_dec_id, {}});
+      // We then get that tuple's first member, which will be an iterator to 
the
+      // existing vec<pair<ImportKind, ImportData>> OR an iterator to our newly
+      // created empty vector (plus its key since this is a hashmap iterator).
+      // we then access the second member of the pair to get access to the
+      // vector directly.
+      auto &imports = tuple.first->second;
+
+      imports.emplace_back (std::make_pair (std::move (rebind_import),
+                                           ImportData::Rebind (def_ns)));
     })
     .has_value ();
 }
 
 void
-Early::build_import_mapping (TopLevel::ImportKind &&import)
+Early::build_import_mapping (
+  std::pair<NodeId, std::vector<TopLevel::ImportKind>> &&use_import)
 {
   auto found = false;
+  auto use_dec_id = use_import.first;
 
-  // We create a copy of the path in case of errors, since the `import` will
-  // be moved into the newly created import mappings
-  auto path = import.to_resolve;
-
-  switch (import.kind)
+  for (auto &&import : use_import.second)
     {
-    case TopLevel::ImportKind::Kind::Glob:
-      found = resolve_glob_import (std::move (import));
-      break;
-    case TopLevel::ImportKind::Kind::Simple:
-      found = resolve_simple_import (std::move (import));
-      break;
-    case TopLevel::ImportKind::Kind::Rebind:
-      found = resolve_rebind_import (std::move (import));
-      break;
-    }
+      // We create a copy of the path in case of errors, since the `import` 
will
+      // be moved into the newly created import mappings
+      auto path = import.to_resolve;
+
+      switch (import.kind)
+       {
+       case TopLevel::ImportKind::Kind::Glob:
+         found = resolve_glob_import (use_dec_id, std::move (import));
+         break;
+       case TopLevel::ImportKind::Kind::Simple:
+         found = resolve_simple_import (use_dec_id, std::move (import));
+         break;
+       case TopLevel::ImportKind::Kind::Rebind:
+         found = resolve_rebind_import (use_dec_id, std::move (import));
+         break;
+       }
 
-  if (!found)
-    rust_error_at (path.get_final_segment ().get_locus (), ErrorCode::E0433,
-                  "unresolved import %qs", path.as_string ().c_str ());
+      if (!found)
+       rust_error_at (path.get_final_segment ().get_locus (), ErrorCode::E0433,
+                      "unresolved import %qs", path.as_string ().c_str ());
+    }
 }
 
 void
diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
index 2ae316295335..a503686508c5 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
@@ -127,20 +127,24 @@ private:
     std::vector<std::unordered_map<std::string, NodeId>> scopes;
   };
 
+  // TODO: This is becoming a very complex type - ugly
   // Mappings between an import and the definition it imports
-  std::map<TopLevel::ImportKind, ImportData> import_mappings;
+  std::unordered_map<NodeId,
+                    std::vector<std::pair<TopLevel::ImportKind, ImportData>>>
+    import_mappings;
 
   // FIXME: Documentation
   // Call this on all the paths of a UseDec - so each flattened path in a
   // UseTreeList for example
   // FIXME: Should that return `found`?
-  bool resolve_simple_import (TopLevel::ImportKind &&import);
-  bool resolve_glob_import (TopLevel::ImportKind &&glob_import);
-  bool resolve_rebind_import (TopLevel::ImportKind &&rebind_import);
+  bool resolve_simple_import (NodeId use_dec_id, TopLevel::ImportKind 
&&import);
+  bool resolve_glob_import (NodeId use_dec_id, TopLevel::ImportKind &&import);
+  bool resolve_rebind_import (NodeId use_dec_id, TopLevel::ImportKind 
&&import);
 
   // Handle an import, resolving it to its definition and adding it to the list
   // of import mappings
-  void build_import_mapping (TopLevel::ImportKind &&import);
+  void build_import_mapping (
+    std::pair<NodeId, std::vector<TopLevel::ImportKind>> &&use_import);
 
   TextualScope textual_scope;
   std::vector<Error> macro_resolve_errors;
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.cc 
b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
index f5c8157f35b5..ac288e3f6e72 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.cc
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
@@ -17,6 +17,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "rust-finalize-imports-2.0.h"
+#include "rust-default-resolver.h"
 #include "rust-hir-map.h"
 #include "rust-name-resolution-context.h"
 #include "rust-rib.h"
@@ -191,11 +192,27 @@ finalize_rebind_import (
                                data.ns.value ());
 }
 
-void
-FinalizeImports::go (
-  std::map<TopLevel::ImportKind, Early::ImportData> import_mappings,
+FinalizeImports::FinalizeImports (
+  std::unordered_map<
+    NodeId, std::vector<std::pair<TopLevel::ImportKind, Early::ImportData>>>
+    &&data,
   TopLevel &toplevel, NameResolutionContext &ctx)
+  : DefaultResolver (ctx), data (std::move (data)), toplevel (toplevel),
+    ctx (ctx)
+{}
+
+void
+FinalizeImports::go (AST::Crate &crate)
 {
+  for (auto &item : crate.items)
+    item->accept_vis (*this);
+}
+
+void
+FinalizeImports::visit (AST::UseDeclaration &use)
+{
+  auto import_mappings = data[use.get_node_id ()];
+
   for (const auto &mapping : import_mappings)
     switch (mapping.first.kind)
       {
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.h 
b/gcc/rust/resolve/rust-finalize-imports-2.0.h
index ed4dc7d1c910..a8b5ba095905 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.h
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.h
@@ -16,6 +16,8 @@
 // along with GCC; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
+#include "rust-ast.h"
+#include "rust-expr.h"
 #include "rust-name-resolution-context.h"
 #include "rust-toplevel-name-resolver-2.0.h"
 #include "rust-early-name-resolver-2.0.h"
@@ -86,12 +88,25 @@ private:
 // each ImportKind - easy!
 //     - yay!
 
-class FinalizeImports
+class FinalizeImports : DefaultResolver
 {
 public:
-  static void
-  go (std::map<TopLevel::ImportKind, Early::ImportData> import_mappings,
-      TopLevel &toplevel, NameResolutionContext &ctx);
+  FinalizeImports (
+    std::unordered_map<
+      NodeId, std::vector<std::pair<TopLevel::ImportKind, Early::ImportData>>>
+      &&data,
+    TopLevel &toplevel, NameResolutionContext &ctx);
+
+  void go (AST::Crate &crate);
+
+private:
+  void visit (AST::UseDeclaration &) override;
+
+  std::unordered_map<
+    NodeId, std::vector<std::pair<TopLevel::ImportKind, Early::ImportData>>>
+    data;
+  TopLevel &toplevel;
+  NameResolutionContext &ctx;
 };
 
 } // namespace Resolver2_0
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 f2f8f359c4c0..47f3adee14c2 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -466,18 +466,22 @@ TopLevel::visit (AST::UseDeclaration &use)
   const auto &tree = use.get_tree ();
   flatten (tree.get (), paths, glob_path, rebind_path, this->ctx);
 
+  auto imports = std::vector<ImportKind> ();
+
   for (auto &&path : paths)
-    imports_to_resolve.emplace_back (
+    imports.emplace_back (
       ImportKind::Simple (std::move (path), values_rib, types_rib, 
macros_rib));
 
   for (auto &&glob : glob_path)
-    imports_to_resolve.emplace_back (
+    imports.emplace_back (
       ImportKind::Glob (std::move (glob), values_rib, types_rib, macros_rib));
 
   for (auto &&rebind : rebind_path)
-    imports_to_resolve.emplace_back (
+    imports.emplace_back (
       ImportKind::Rebind (std::move (rebind.first), std::move (rebind.second),
                          values_rib, types_rib, macros_rib));
+
+  imports_to_resolve.insert ({use.get_node_id (), std::move (imports)});
 }
 
 } // 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 92a964d2c14f..acb60d36e133 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -106,7 +106,8 @@ public:
     {}
   };
 
-  std::vector<ImportKind> &&get_imports_to_resolve ()
+  std::unordered_map<NodeId, std::vector<ImportKind>> &&
+  get_imports_to_resolve ()
   {
     return std::move (imports_to_resolve);
   }
@@ -137,7 +138,7 @@ private:
 
   // One of the outputs of the `TopLevel` visitor - the list of imports that
   // `Early` should take care of resolving
-  std::vector<ImportKind> imports_to_resolve;
+  std::unordered_map<NodeId, std::vector<ImportKind>> imports_to_resolve;
 
   void visit (AST::Module &module) override;
   void visit (AST::Trait &trait) override;

Reply via email to