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

gcc/rust/ChangeLog:

        * resolve/rust-early-name-resolver-2.0.cc (Early::resolve_glob_import):
        Use ImportData class.
        (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-finalize-imports-2.0.cc (finalize_simple_import): 
Likewise.
        (finalize_glob_import): Likewise.
        (finalize_rebind_import): Likewise.
        (FinalizeImports::go): Likewise.
        * resolve/rust-finalize-imports-2.0.h: Likewise.
        * resolve/rust-name-resolution-context.h: Likewise.
        * resolve/rust-rib.h: Define ImportData class.
---
 .../resolve/rust-early-name-resolver-2.0.cc   | 91 +++----------------
 .../resolve/rust-early-name-resolver-2.0.h    | 37 +++++++-
 gcc/rust/resolve/rust-finalize-imports-2.0.cc | 35 ++++---
 gcc/rust/resolve/rust-finalize-imports-2.0.h  |  6 +-
 .../resolve/rust-name-resolution-context.h    | 27 ++++++
 gcc/rust/resolve/rust-rib.h                   |  2 +-
 6 files changed, 102 insertions(+), 96 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 41d0a075bbb..ba73a54d412 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -83,7 +83,8 @@ 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`
-  import_mappings.insert ({std::move (glob), resolved->get_node_id ()});
+  // The namespace does not matter here since we are dealing with a glob
+  import_mappings.insert ({std::move (glob), ImportData::Glob (*resolved)});
 
   return true;
 }
@@ -91,89 +92,21 @@ Early::resolve_glob_import (TopLevel::ImportKind &&glob)
 bool
 Early::resolve_simple_import (TopLevel::ImportKind &&import)
 {
-  // TODO: Fix documentation - the function has changed slightly
-
-  const auto &path = import.to_resolve;
-  // auto locus = path.get_final_segment ().get_locus ();
-  // auto declared_name = path.get_final_segment ().as_string ();
-
-  // In that function, we only need to declare a new definition - the use path.
-  // the resolution needs to happpen in the EarlyNameResolver. So the
-  // definitions we'll add will be the path's NodeId - that makes sense, as we
-  // need one definition per path declared in a Use tree. so all good.
-  // alright, now in what namespace do we declare them? all of them? do we only
-  // declare them in the EarlyNameResolver? this is dodgy
-
-  // in what namespace do we perform path resolution? All of them? see which 
one
-  // matches? Error out on ambiguities?
-  // so, apparently, for each one that matches, add it to the proper namespace
-  // :(
-
-  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 ()); 
})
-    .map ([&] (Rib::Definition def) {
-      import_mappings.insert ({std::move (import), def.get_node_id ()});
+  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)});
     })
     .has_value ();
-
-  //    switch (ns)
-  //      {
-  //      case Namespace::Values:
-  // resolved = ctx.values.resolve_path (path.get_segments ());
-  // break;
-  //      case Namespace::Types:
-  // resolved = ctx.types.resolve_path (path.get_segments ());
-  // break;
-  //      case Namespace::Macros:
-  // resolved = ctx.macros.resolve_path (path.get_segments ());
-  // break;
-  //      case Namespace::Labels:
-  // // TODO: Is that okay?
-  // rust_unreachable ();
-  //      }
-
-  // FIXME: Ugly
-  //   (void) resolved.map ([this, &found, path, import] (Rib::Definition
-  //   def) {
-  //     found = true;
-
-  //     import_mappings.insert ({std::move (import), def.get_node_id
-  //     ()});
-
-  //     // what do we do with the id?
-  //     // insert_or_error_out (declared_name, locus, def.get_node_id (),
-  //     // ns); auto result = node_forwarding.find (def.get_node_id ());
-  //     if
-  //     // (result != node_forwarding.cend ()
-  //     //     && result->second != path.get_node_id ())
-  //     //   rust_error_at (path.get_locus (), "%qs defined multiple
-  //     times",
-  //     //    declared_name.c_str ());
-  //     // else // No previous thing has inserted this into our scope
-  //     //   node_forwarding.insert ({def.get_node_id (),
-  //     path.get_node_id
-  //     //   ()});
-
-  //     return def.get_node_id ();
-  //   });
-  // };
-
-  // resolve_and_insert (path);
-
-  // return found;
 }
 
 bool
 Early::resolve_rebind_import (TopLevel::ImportKind &&rebind_import)
 {
-  auto &path = rebind_import.to_resolve;
-
-  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 ()); 
})
-    .map ([&] (Rib::Definition def) {
-      import_mappings.insert ({std::move (rebind_import), def.get_node_id ()});
+  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)});
     })
     .has_value ();
 }
@@ -183,8 +116,8 @@ Early::build_import_mapping (TopLevel::ImportKind &&import)
 {
   auto found = false;
 
-  // We create a copy of the path in case of errors, since the `import` will be
-  // moved into the newly created import mappings
+  // 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)
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 6651bd2acfd..2ae31629533 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
@@ -24,6 +24,7 @@
 #include "rust-ast-visitor.h"
 #include "rust-name-resolution-context.h"
 #include "rust-default-resolver.h"
+#include "rust-rib.h"
 #include "rust-toplevel-name-resolver-2.0.h"
 
 namespace Rust {
@@ -55,6 +56,40 @@ public:
   void visit (AST::Function &) override;
   void visit (AST::StructStruct &) override;
 
+  struct ImportData
+  {
+    enum class Kind
+    {
+      Simple,
+      Glob,
+      Rebind
+    } kind;
+
+    Rib::Definition definition;
+    tl::optional<Namespace> ns;
+
+    static ImportData Simple (std::pair<Rib::Definition, Namespace> def_ns)
+    {
+      return ImportData (Kind::Simple, def_ns.first, def_ns.second);
+    }
+
+    static ImportData Rebind (std::pair<Rib::Definition, Namespace> def_ns)
+    {
+      return ImportData (Kind::Rebind, def_ns.first, def_ns.second);
+    }
+
+    static ImportData Glob (Rib::Definition module)
+    {
+      return ImportData (Kind::Glob, module);
+    }
+
+  private:
+    ImportData (Kind kind, Rib::Definition definition,
+               tl::optional<Namespace> ns = tl::nullopt)
+      : kind (kind), definition (definition), ns (ns)
+    {}
+  };
+
 private:
   void visit_attributes (std::vector<AST::Attribute> &attrs);
 
@@ -93,7 +128,7 @@ private:
   };
 
   // Mappings between an import and the definition it imports
-  std::map<TopLevel::ImportKind, NodeId> import_mappings;
+  std::map<TopLevel::ImportKind, ImportData> import_mappings;
 
   // FIXME: Documentation
   // Call this on all the paths of a UseDec - so each flattened path in a
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.cc 
b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
index 1725e71e17b..f5c8157f35b 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.cc
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
@@ -125,25 +125,30 @@ GlobbingVisitor::visit (AST::UseDeclaration &use)
 }
 
 void
-finalize_simple_import (TopLevel &toplevel,
-                       const std::pair<TopLevel::ImportKind, NodeId> &mapping)
+finalize_simple_import (
+  TopLevel &toplevel,
+  const std::pair<TopLevel::ImportKind, Early::ImportData> &mapping)
 {
   // FIXME: We probably need to store namespace information
 
   auto locus = mapping.first.to_resolve.get_locus ();
-  auto def = mapping.second;
+  auto data = 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);
+  toplevel.insert_or_error_out (identifier, locus,
+                               data.definition.get_node_id (),
+                               data.ns.value ());
 }
 
 void
-finalize_glob_import (NameResolutionContext &ctx,
-                     const std::pair<TopLevel::ImportKind, NodeId> &mapping)
+finalize_glob_import (
+  NameResolutionContext &ctx,
+  const std::pair<TopLevel::ImportKind, Early::ImportData> &mapping)
 {
-  auto module = Analysis::Mappings::get ().lookup_ast_module (mapping.second);
+  auto module = Analysis::Mappings::get ().lookup_ast_module (
+    mapping.second.definition.get_node_id ());
   rust_assert (module);
 
   GlobbingVisitor glob_visitor (ctx);
@@ -151,14 +156,15 @@ finalize_glob_import (NameResolutionContext &ctx,
 }
 
 void
-finalize_rebind_import (TopLevel &toplevel,
-                       const std::pair<TopLevel::ImportKind, NodeId> &mapping)
+finalize_rebind_import (
+  TopLevel &toplevel,
+  const std::pair<TopLevel::ImportKind, Early::ImportData> &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;
+  auto data = mapping.second;
 
   location_t locus = UNKNOWN_LOCATION;
   std::string declared_name;
@@ -180,12 +186,15 @@ finalize_rebind_import (TopLevel &toplevel,
     }
 
   // FIXME: Fix the namespace in which we insert the new definition
-  toplevel.insert_or_error_out (declared_name, locus, def, Namespace::Values);
+  toplevel.insert_or_error_out (declared_name, locus,
+                               data.definition.get_node_id (),
+                               data.ns.value ());
 }
 
 void
-FinalizeImports::go (std::map<TopLevel::ImportKind, NodeId> import_mappings,
-                    TopLevel &toplevel, NameResolutionContext &ctx)
+FinalizeImports::go (
+  std::map<TopLevel::ImportKind, Early::ImportData> import_mappings,
+  TopLevel &toplevel, NameResolutionContext &ctx)
 {
   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 e566a485275..ed4dc7d1c91 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.h
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.h
@@ -18,6 +18,7 @@
 
 #include "rust-name-resolution-context.h"
 #include "rust-toplevel-name-resolver-2.0.h"
+#include "rust-early-name-resolver-2.0.h"
 
 namespace Rust {
 namespace Resolver2_0 {
@@ -88,8 +89,9 @@ private:
 class FinalizeImports
 {
 public:
-  static void go (std::map<TopLevel::ImportKind, NodeId> import_mappings,
-                 TopLevel &toplevel, NameResolutionContext &ctx);
+  static void
+  go (std::map<TopLevel::ImportKind, Early::ImportData> import_mappings,
+      TopLevel &toplevel, NameResolutionContext &ctx);
 };
 
 } // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h 
b/gcc/rust/resolve/rust-name-resolution-context.h
index 36053929d07..2fc8528ed3f 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -22,6 +22,7 @@
 #include "optional.h"
 #include "rust-forever-stack.h"
 #include "rust-hir-map.h"
+#include "rust-rib.h"
 
 namespace Rust {
 namespace Resolver2_0 {
@@ -198,6 +199,32 @@ public:
               std::function<void (void)> lambda,
               tl::optional<Identifier> path = {});
 
+  template <typename P>
+  tl::optional<std::pair<Rib::Definition, Namespace>>
+  resolve_path (const P &path)
+  {
+    const auto &segments = path.get_segments ();
+
+    // Pair a definition with the namespace it was found in
+    auto pair_with_ns = [] (Namespace ns) {
+      return [ns] (Rib::Definition def) { return std::make_pair (def, ns); };
+    };
+
+    // We first check in values, if not found then types, if not found then
+    // macros. There should not be any ambiguity at this point - this function
+    // will short circuit and return the first definition it has found.
+    return values.resolve_path (segments)
+      .map (pair_with_ns (Namespace::Values))
+      .or_else ([&] () {
+       return types.resolve_path (segments).map (
+         pair_with_ns (Namespace::Types));
+      })
+      .or_else ([&] () {
+       return macros.resolve_path (segments).map (
+         pair_with_ns (Namespace::Macros));
+      });
+  }
+
   ForeverStack<Namespace::Values> values;
   ForeverStack<Namespace::Types> types;
   ForeverStack<Namespace::Macros> macros;
diff --git a/gcc/rust/resolve/rust-rib.h b/gcc/rust/resolve/rust-rib.h
index 3228a3c4eac..11a6b56abce 100644
--- a/gcc/rust/resolve/rust-rib.h
+++ b/gcc/rust/resolve/rust-rib.h
@@ -124,7 +124,7 @@ public:
 
     bool is_ambiguous () const;
 
-    NodeId get_node_id ()
+    NodeId get_node_id () const
     {
       rust_assert (!is_ambiguous ());
       return ids[0];
-- 
2.45.2

Reply via email to