From: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>

Import mapping was relying on resolve_path which in turn relies on
the cursor function. This means the mapping resolver should be called
from the correct scope instead of being called from the crate scope.

gcc/rust/ChangeLog:

        * resolve/rust-early-name-resolver-2.0.cc (Early::Early): Move the
        top level visitor from the function scope to attributes.
        (Early::go): Remove top level visitor creation and adapt calling code.
        Remove call to mapping resolution and import finalization.
        (Early::finalize_simple_import): Move the finalization from it's
        visitor.
        (Early::finalize_glob_import): Likewise.
        (Early::finalize_rebind_import): Likewise.
        (Early::visit): Add mapping resolution and finalization in
        UseDeclaration visitor function.
        * resolve/rust-finalize-imports-2.0.cc (finalize_simple_import): Move
        function.
        (finalize_glob_import): Likewise.
        (finalize_rebind_import): Likewise.
        (FinalizeImports::visit): Remove call to finalizers.
        * resolve/rust-early-name-resolver-2.0.h (class Early): Add top level
        attribute.
        * resolve/rust-finalize-imports-2.0.h: Add function prototypes.
        * resolve/rust-toplevel-name-resolver-2.0.h: Change getter return type
        to reference.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>
---
 .../resolve/rust-early-name-resolver-2.0.cc   | 98 +++++++++++++++++--
 .../resolve/rust-early-name-resolver-2.0.h    |  9 ++
 gcc/rust/resolve/rust-finalize-imports-2.0.cc | 79 +--------------
 gcc/rust/resolve/rust-finalize-imports-2.0.h  |  4 +-
 .../resolve/rust-toplevel-name-resolver-2.0.h |  5 +-
 5 files changed, 105 insertions(+), 90 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 b894d130ccf..492a665f43e 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -27,7 +27,8 @@
 namespace Rust {
 namespace Resolver2_0 {
 
-Early::Early (NameResolutionContext &ctx) : DefaultResolver (ctx), dirty 
(false)
+Early::Early (NameResolutionContext &ctx)
+  : DefaultResolver (ctx), toplevel (TopLevel (ctx)), dirty (false)
 {}
 
 void
@@ -52,16 +53,10 @@ void
 Early::go (AST::Crate &crate)
 {
   // First we go through TopLevel resolution to get all our declared items
-  auto toplevel = TopLevel (ctx);
   toplevel.go (crate);
 
   // We start with resolving the list of imports that `TopLevel` has built for
   // us
-  for (auto &&import : toplevel.get_imports_to_resolve ())
-    build_import_mapping (std::move (import));
-
-  // Once this is done, we finalize their resolution
-  FinalizeImports (std::move (import_mappings), toplevel, ctx).go (crate);
 
   dirty = toplevel.is_dirty ();
   // We now proceed with resolving macros, which can be nested in almost any
@@ -375,5 +370,94 @@ Early::visit (AST::StructStruct &s)
   DefaultResolver::visit (s);
 }
 
+void
+Early::finalize_simple_import (const Early::ImportPair &mapping)
+{
+  // FIXME: We probably need to store namespace information
+
+  auto locus = mapping.import_kind.to_resolve.get_locus ();
+  auto data = mapping.data;
+  auto identifier
+    = mapping.import_kind.to_resolve.get_final_segment ().get_segment_name ();
+
+  for (auto &&definition : data.definitions ())
+    toplevel
+      .insert_or_error_out (
+       identifier, locus, definition.first.get_node_id (), definition.second 
/* TODO: This isn't clear - it would be better if it was called .ns or 
something */);
+}
+
+void
+Early::finalize_glob_import (NameResolutionContext &ctx,
+                            const Early::ImportPair &mapping)
+{
+  auto module = Analysis::Mappings::get ().lookup_ast_module (
+    mapping.data.module ().get_node_id ());
+  rust_assert (module);
+
+  GlobbingVisitor glob_visitor (ctx);
+  glob_visitor.go (module.value ());
+}
+
+void
+Early::finalize_rebind_import (const Early::ImportPair &mapping)
+{
+  // We can fetch the value here as `resolve_rebind` will only be called on
+  // imports of the right kind
+  auto &path = mapping.import_kind.to_resolve;
+  auto &rebind = mapping.import_kind.rebind.value ();
+  auto data = mapping.data;
+
+  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;
+    }
+
+  for (auto &&definition : data.definitions ())
+    toplevel.insert_or_error_out (
+      declared_name, locus, definition.first.get_node_id (), definition.second 
/* TODO: This isn't clear - it would be better if it was called .ns or 
something */);
+}
+
+void
+Early::visit (AST::UseDeclaration &decl)
+{
+  auto &imports = toplevel.get_imports_to_resolve ();
+  auto current_import = imports.find (decl.get_node_id ());
+  if (current_import != imports.end ())
+    {
+      build_import_mapping (*current_import);
+    }
+
+  // Once this is done, we finalize their resolution
+  for (const auto &mapping : import_mappings.get (decl.get_node_id ()))
+    switch (mapping.import_kind.kind)
+      {
+      case TopLevel::ImportKind::Kind::Glob:
+       finalize_glob_import (ctx, mapping);
+       break;
+      case TopLevel::ImportKind::Kind::Simple:
+       finalize_simple_import (mapping);
+       break;
+      case TopLevel::ImportKind::Kind::Rebind:
+       finalize_rebind_import (mapping);
+       break;
+      }
+
+  DefaultResolver::visit (decl);
+}
+
 } // namespace Resolver2_0
 } // namespace Rust
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 e309b50174c..c4226fe9ea8 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
@@ -34,6 +34,7 @@ class Early : public DefaultResolver
 {
   using DefaultResolver::visit;
 
+  TopLevel toplevel;
   bool dirty;
 
 public:
@@ -59,6 +60,7 @@ public:
 
   void visit (AST::Function &) override;
   void visit (AST::StructStruct &) override;
+  void visit (AST::UseDeclaration &) override;
 
   struct ImportData
   {
@@ -246,6 +248,13 @@ private:
   std::vector<Error> macro_resolve_errors;
 
   void collect_error (Error e) { macro_resolve_errors.push_back (e); }
+
+  void finalize_simple_import (const Early::ImportPair &mapping);
+
+  void finalize_glob_import (NameResolutionContext &ctx,
+                            const Early::ImportPair &mapping);
+
+  void finalize_rebind_import (const Early::ImportPair &mapping);
 };
 
 } // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.cc 
b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
index 71916ae432b..bd6002a09f4 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.cc
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
@@ -125,67 +125,6 @@ GlobbingVisitor::visit (AST::UseDeclaration &use)
   // Handle cycles ?
 }
 
-void
-finalize_simple_import (TopLevel &toplevel, const Early::ImportPair &mapping)
-{
-  // FIXME: We probably need to store namespace information
-
-  auto locus = mapping.import_kind.to_resolve.get_locus ();
-  auto data = mapping.data;
-  auto identifier
-    = mapping.import_kind.to_resolve.get_final_segment ().get_segment_name ();
-
-  for (auto &&definition : data.definitions ())
-    toplevel
-      .insert_or_error_out (
-       identifier, locus, definition.first.get_node_id (), definition.second 
/* TODO: This isn't clear - it would be better if it was called .ns or 
something */);
-}
-
-void
-finalize_glob_import (NameResolutionContext &ctx,
-                     const Early::ImportPair &mapping)
-{
-  auto module = Analysis::Mappings::get ().lookup_ast_module (
-    mapping.data.module ().get_node_id ());
-  rust_assert (module);
-
-  GlobbingVisitor glob_visitor (ctx);
-  glob_visitor.go (module.value ());
-}
-
-void
-finalize_rebind_import (TopLevel &toplevel, const Early::ImportPair &mapping)
-{
-  // We can fetch the value here as `resolve_rebind` will only be called on
-  // imports of the right kind
-  auto &path = mapping.import_kind.to_resolve;
-  auto &rebind = mapping.import_kind.rebind.value ();
-  auto data = mapping.data;
-
-  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;
-    }
-
-  for (auto &&definition : data.definitions ())
-    toplevel.insert_or_error_out (
-      declared_name, locus, definition.first.get_node_id (), definition.second 
/* TODO: This isn't clear - it would be better if it was called .ns or 
something */);
-}
-
 FinalizeImports::FinalizeImports (Early::ImportMappings &&data,
                                  TopLevel &toplevel,
                                  NameResolutionContext &ctx)
@@ -202,23 +141,7 @@ FinalizeImports::go (AST::Crate &crate)
 
 void
 FinalizeImports::visit (AST::UseDeclaration &use)
-{
-  auto import_mappings = data.get (use.get_node_id ());
-
-  for (const auto &mapping : import_mappings)
-    switch (mapping.import_kind.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
index 0fba5a517a1..a06fe538846 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.h
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.h
@@ -96,11 +96,11 @@ public:
 
   void go (AST::Crate &crate);
 
+  void visit (AST::UseDeclaration &) override;
+
 private:
   using AST::DefaultASTVisitor::visit;
 
-  void visit (AST::UseDeclaration &) override;
-
   Early::ImportMappings data;
   TopLevel &toplevel;
   NameResolutionContext &ctx;
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 559c0d8757f..3ff37eda16d 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -108,10 +108,9 @@ public:
     {}
   };
 
-  std::unordered_map<NodeId, std::vector<ImportKind>> &&
-  get_imports_to_resolve ()
+  std::unordered_map<NodeId, std::vector<ImportKind>> &get_imports_to_resolve 
()
   {
-    return std::move (imports_to_resolve);
+    return imports_to_resolve;
   }
 
   void check_multiple_insertion_error (
-- 
2.45.2

Reply via email to