[gccrs COMMIT 02/19] nr: Finish moving all segment resolution methods to NRCtx

gerris.rs@gmail.com gerris.rs@gmail.com
Thu Jun 4 13:13:35 GMT 2026


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

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



More information about the Gcc-rust mailing list