From: Arthur Cohen <[email protected]>

gcc/rust/ChangeLog:

        * resolve/rust-forever-stack.h: Move resolve_segments and 
resolve_final_segment to...
        * resolve/rust-forever-stack.hxx: Likewise.
        * resolve/rust-name-resolution-context.h: ...here.
        * resolve/rust-name-resolution-context.hxx: Likewise.
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/dfdd26a6c4f44a0376dd9187b388eaf1b154c36a

The commit has NOT been mentioned in any issue.

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4551

 gcc/rust/resolve/rust-forever-stack.h         |  10 --
 gcc/rust/resolve/rust-forever-stack.hxx       | 141 ----------------
 .../resolve/rust-name-resolution-context.h    |  75 +++++----
 .../resolve/rust-name-resolution-context.hxx  | 155 +++++++++++++++++-
 4 files changed, 195 insertions(+), 186 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index 242b588a3..c28828fda 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -868,16 +868,6 @@ public:
     std::function<void (Usage, Definition)> insert_segment_resolution,
     std::vector<Error> &collect_errors);
 
-  tl::optional<Node &> resolve_segments (
-    Node &starting_point, const std::vector<ResolutionPath::Segment> &segments,
-    SegIterator iterator,
-    std::function<void (Usage, Definition)> insert_segment_resolution,
-    std::vector<Error> &collect_errors);
-
-  tl::optional<Rib::Definition> resolve_final_segment (Node &final_node,
-                                                      std::string &seg_name,
-                                                      bool is_lower_self);
-
   /* Helper functions for forward resolution (to_canonical_path, to_rib...) */
   struct DfsResult
   {
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index e3cd5b7ad..9f1a2cdb5 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -526,147 +526,6 @@ ForeverStack<N>::find_starting_point (
   return iterator;
 }
 
-template <Namespace N>
-tl::optional<typename ForeverStack<N>::Node &>
-ForeverStack<N>::resolve_segments (
-  Node &starting_point, const std::vector<ResolutionPath::Segment> &segments,
-  typename std::vector<ResolutionPath::Segment>::const_iterator iterator,
-  std::function<void (Usage, Definition)> insert_segment_resolution,
-  std::vector<Error> &collect_errors)
-{
-  Node *current_node = &starting_point;
-  for (; !is_last (iterator, segments); iterator++)
-    {
-      auto &seg = *iterator;
-
-      std::string str = seg.name;
-      rust_debug ("[ARTHUR]: resolving segment part: %s", str.c_str ());
-
-      // check that we don't encounter *any* leading keywords afterwards
-      if (check_leading_kw_at_start (collect_errors, seg,
-                                    seg.is_crate_path_seg ()
-                                      || seg.is_super_path_seg ()
-                                      || seg.is_lower_self_seg ()))
-       return tl::nullopt;
-
-      tl::optional<std::reference_wrapper<Node>> child = tl::nullopt;
-
-      /*
-       * On every iteration this loop either
-       *
-       * 1. terminates
-       *
-       * 2. decreases the depth of the node pointed to by current_node until
-       *    current_node reaches the root
-       *
-       * 3. If the root node is reached, and we were not able to resolve the
-       *    segment, we search the prelude rib for the segment, by setting
-       *    current_node to point to the prelude, and toggling the
-       *    searched_prelude boolean to true. If current_node is the prelude
-       *    rib, and searched_prelude is true, we will exit.
-       *
-       * This ensures termination.
-       *
-       */
-      bool searched_prelude = false;
-      while (true)
-       {
-         if (is_start (iterator, segments)
-             && current_node->rib.kind == Rib::Kind::TraitOrImpl)
-           {
-             // we can't reference associated types/functions like this
-             current_node = &current_node->parent.value ();
-             continue;
-           }
-
-         // may set the value of child
-         for (auto &kv : current_node->children)
-           {
-             auto &link = kv.first;
-
-             if (link.path.map_or (
-                   [&str] (Identifier path) {
-                     auto &path_str = path.as_string ();
-                     return str == path_str;
-                   },
-                   false))
-               {
-                 child = kv.second;
-                 break;
-               }
-           }
-
-         if (child.has_value ())
-           {
-             break;
-           }
-
-         auto rib_lookup = current_node->rib.get (seg.name);
-         if (rib_lookup && !rib_lookup->is_ambiguous ())
-           {
-             if (Analysis::Mappings::get ()
-                   .lookup_glob_container (rib_lookup->get_node_id ())
-                   .has_value ())
-               {
-                 child = dfs_node (root, rib_lookup->get_node_id ()).value ();
-                 break;
-               }
-             else
-               {
-                 insert_segment_resolution (Usage (seg.node_id),
-                                            Definition (
-                                              rib_lookup->get_node_id ()));
-                 return tl::nullopt;
-               }
-           }
-
-         if (current_node->is_root () && !searched_prelude)
-           {
-             searched_prelude = true;
-             current_node = &lang_prelude;
-             continue;
-           }
-
-         if (!is_start (iterator, segments)
-             || current_node->rib.kind == Rib::Kind::Module
-             || current_node->is_prelude ())
-           {
-             return tl::nullopt;
-           }
-
-         current_node = &current_node->parent.value ();
-       }
-
-      // if child didn't point to a value
-      // the while loop above would have returned or kept looping
-      current_node = &child->get ();
-      insert_segment_resolution (Usage (seg.node_id),
-                                Definition (current_node->id));
-    }
-
-  return *current_node;
-}
-
-template <>
-inline tl::optional<Rib::Definition>
-ForeverStack<Namespace::Types>::resolve_final_segment (Node &final_node,
-                                                      std::string &seg_name,
-                                                      bool is_lower_self)
-{
-  if (is_lower_self)
-    return Rib::Definition::NonShadowable (final_node.id);
-  else
-    return final_node.rib.get (seg_name);
-}
-
-template <Namespace N>
-tl::optional<Rib::Definition>
-ForeverStack<N>::resolve_final_segment (Node &final_node, std::string 
&seg_name,
-                                       bool is_lower_self)
-{
-  return final_node.rib.get (seg_name);
-}
-
 template <Namespace N>
 tl::optional<typename ForeverStack<N>::DfsResult>
 ForeverStack<N>::dfs (ForeverStack<N>::Node &starting_point, NodeId to_find)
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h 
b/gcc/rust/resolve/rust-name-resolution-context.h
index 6f18115ba..f58f130a1 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -774,37 +774,6 @@ public:
                         std::forward<Args> (args)...);
   }
 
-  /**
-   * Resolve a path to its definition in the current `ForeverStack`
-   *
-   * // TODO: Add documentation for `segments`
-   *
-   * @return a valid option with the Definition if the path is present in the
-   *         current map, an empty one otherwise.
-   */
-  template <Namespace N>
-  tl::optional<Rib::Definition> resolve_path (
-    ForeverStack<N> &stack, const ResolutionPath &path, ResolutionMode mode,
-    std::function<void (Usage, Definition)> insert_segment_resolution,
-    std::vector<Error> &collect_errors);
-
-  template <Namespace N>
-  tl::optional<Rib::Definition> resolve_path (
-    ForeverStack<N> &stack, const ResolutionPath &path, ResolutionMode mode,
-    std::function<void (Usage, Definition)> insert_segment_resolution,
-    std::vector<Error> &collect_errors, NodeId starting_point_id);
-
-  /* TODO: Make private? */
-  template <Namespace N>
-  tl::optional<Rib::Definition> resolve_path (
-    ForeverStack<N> &stack, const ResolutionPath &path, ResolutionMode mode,
-    std::function<void (Usage, Definition)> insert_segment_resolution,
-    std::vector<Error> &collect_errors,
-    std::reference_wrapper<typename ForeverStack<N>::Node> starting_point);
-
-  /* If declared with #[prelude_import], the current standard library module */
-  tl::optional<NodeId> prelude;
-
   enum class LookupFinalizeError
   {
     // Impossible - we did not find any definition corresponding to a Usage.
@@ -838,7 +807,51 @@ public:
    */
   void flatten ();
 
+  /* If declared with #[prelude_import], the current standard library module */
+  tl::optional<NodeId> prelude;
+
 private:
+  /**
+   * Resolve a path to its definition
+   *
+   * // TODO: Add documentation for `segments`
+   *
+   * @return a valid option with the Definition if the path is present in the
+   *         current map, an empty one otherwise.
+   */
+  template <Namespace N>
+  tl::optional<Rib::Definition> resolve_path (
+    ForeverStack<N> &stack, const ResolutionPath &path, ResolutionMode mode,
+    std::function<void (Usage, Definition)> insert_segment_resolution,
+    std::vector<Error> &collect_errors);
+
+  template <Namespace N>
+  tl::optional<Rib::Definition> resolve_path (
+    ForeverStack<N> &stack, const ResolutionPath &path, ResolutionMode mode,
+    std::function<void (Usage, Definition)> insert_segment_resolution,
+    std::vector<Error> &collect_errors, NodeId starting_point_id);
+
+  template <Namespace N>
+  tl::optional<Rib::Definition> resolve_path (
+    ForeverStack<N> &stack, const ResolutionPath &path, ResolutionMode mode,
+    std::function<void (Usage, Definition)> insert_segment_resolution,
+    std::vector<Error> &collect_errors,
+    std::reference_wrapper<typename ForeverStack<N>::Node> starting_point);
+
+  template <Namespace N>
+  tl::optional<typename ForeverStack<N>::Node &> resolve_segments (
+    ForeverStack<N> &stack, typename ForeverStack<N>::Node &starting_point,
+    const std::vector<ResolutionPath::Segment> &segments,
+    typename ForeverStack<N>::SegIterator iterator,
+    std::function<void (Usage, Definition)> insert_segment_resolution,
+    std::vector<Error> &collect_errors);
+
+  template <Namespace N>
+  tl::optional<Rib::Definition>
+  resolve_final_segment (ForeverStack<N> &stack,
+                        typename ForeverStack<N>::Node &final_node,
+                        std::string &seg_name, bool is_lower_self);
+
   /* Map of "usage" nodes which have been resolved to a "definition" node */
   std::map<Usage, Definition> resolved_nodes;
 };
diff --git a/gcc/rust/resolve/rust-name-resolution-context.hxx 
b/gcc/rust/resolve/rust-name-resolution-context.hxx
index a5fc4965a..28c7dcccf 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.hxx
+++ b/gcc/rust/resolve/rust-name-resolution-context.hxx
@@ -17,6 +17,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "optional.h"
+#include "rust-forever-stack.h"
 #include "rust-name-resolution-context.h"
 
 /**
@@ -211,8 +212,8 @@ NameResolutionContext::resolve_path (
   // NodeId as a starting point rather than a Node?
 
   auto node
-    = types.resolve_segments (types_starting_point.value (), segments, 
iterator,
-                             insert_segment_resolution, collect_errors);
+    = resolve_segments (types, types_starting_point.value (), segments,
+                       iterator, insert_segment_resolution, collect_errors);
 
   if (!node)
     return tl::nullopt;
@@ -231,8 +232,8 @@ NameResolutionContext::resolve_path (
   std::string seg_name = seg.name;
 
   tl::optional<Rib::Definition> res
-    = stack.resolve_final_segment (final_node, seg_name,
-                                  seg.is_lower_self_seg ());
+    = resolve_final_segment (stack, final_node, seg_name,
+                            seg.is_lower_self_seg ());
   // Ok we didn't find it in the rib, Lets try the prelude...
   if (!res)
     res = stack.get_lang_prelude (seg_name);
@@ -265,5 +266,151 @@ NameResolutionContext::resolve_path (
   return res;
 }
 
+template <Namespace N>
+tl::optional<typename ForeverStack<N>::Node &>
+NameResolutionContext::resolve_segments (
+  ForeverStack<N> &stack, typename ForeverStack<N>::Node &starting_point,
+  const std::vector<ResolutionPath::Segment> &segments,
+  typename ForeverStack<N>::SegIterator iterator,
+  std::function<void (Usage, Definition)> insert_segment_resolution,
+  std::vector<Error> &collect_errors)
+{
+  auto *current_node = &starting_point;
+  for (; !is_last (iterator, segments); iterator++)
+    {
+      auto &seg = *iterator;
+
+      std::string str = seg.name;
+
+      // check that we don't encounter *any* leading keywords afterwards
+      if (check_leading_kw_at_start (collect_errors, seg,
+                                    seg.is_crate_path_seg ()
+                                      || seg.is_super_path_seg ()
+                                      || seg.is_lower_self_seg ()))
+       return tl::nullopt;
+
+      tl::optional<std::reference_wrapper<typename ForeverStack<N>::Node>> 
child
+       = tl::nullopt;
+
+      /*
+       * On every iteration this loop either
+       *
+       * 1. terminates
+       *
+       * 2. decreases the depth of the node pointed to by current_node until
+       *    current_node reaches the root
+       *
+       * 3. If the root node is reached, and we were not able to resolve the
+       *    segment, we search the prelude rib for the segment, by setting
+       *    current_node to point to the prelude, and toggling the
+       *    searched_prelude boolean to true. If current_node is the prelude
+       *    rib, and searched_prelude is true, we will exit.
+       *
+       * This ensures termination.
+       *
+       */
+      bool searched_prelude = false;
+      while (true)
+       {
+         if (is_start (iterator, segments)
+             && current_node->rib.kind == Rib::Kind::TraitOrImpl)
+           {
+             // we can't reference associated types/functions like this
+             current_node = &current_node->parent.value ();
+             continue;
+           }
+
+         // may set the value of child
+         for (auto &kv : current_node->children)
+           {
+             auto &link = kv.first;
+
+             if (link.path.map_or (
+                   [&str] (Identifier path) {
+                     auto &path_str = path.as_string ();
+                     return str == path_str;
+                   },
+                   false))
+               {
+                 child = kv.second;
+                 break;
+               }
+           }
+
+         if (child.has_value ())
+           {
+             break;
+           }
+
+         auto rib_lookup = current_node->rib.get (seg.name);
+         if (rib_lookup && !rib_lookup->is_ambiguous ())
+           {
+             if (Analysis::Mappings::get ()
+                   .lookup_glob_container (rib_lookup->get_node_id ())
+                   .has_value ())
+               {
+                 child
+                   = stack.dfs_node (stack.root, rib_lookup->get_node_id ())
+                       .value ();
+                 break;
+               }
+             else
+               {
+                 insert_segment_resolution (Usage (seg.node_id),
+                                            Definition (
+                                              rib_lookup->get_node_id ()));
+                 return tl::nullopt;
+               }
+           }
+
+         if (current_node->is_root () && !searched_prelude)
+           {
+             searched_prelude = true;
+             current_node = &stack.lang_prelude;
+             continue;
+           }
+
+         if (!is_start (iterator, segments)
+             || current_node->rib.kind == Rib::Kind::Module
+             || current_node->is_prelude ())
+           {
+             return tl::nullopt;
+           }
+
+         current_node = &current_node->parent.value ();
+       }
+
+      // if child didn't point to a value
+      // the while loop above would have returned or kept looping
+      current_node = &child->get ();
+      insert_segment_resolution (Usage (seg.node_id),
+                                Definition (current_node->id));
+    }
+
+  return *current_node;
+}
+
+template <>
+inline tl::optional<Rib::Definition>
+NameResolutionContext::resolve_final_segment (
+  ForeverStack<Namespace::Types> &stack,
+  typename ForeverStack<Namespace::Types>::Node &final_node,
+  std::string &seg_name, bool is_lower_self)
+{
+  if (is_lower_self)
+    return Rib::Definition::NonShadowable (final_node.id);
+  else
+    return final_node.rib.get (seg_name);
+}
+
+template <Namespace N>
+tl::optional<Rib::Definition>
+NameResolutionContext::resolve_final_segment (
+  ForeverStack<N> &stack, typename ForeverStack<N>::Node &final_node,
+  std::string &seg_name, bool is_lower_self)
+{
+  return final_node.rib.get (seg_name);
+}
+
 } // namespace Resolver2_0
 } // namespace Rust
-- 
2.54.0

Reply via email to