[COMMITTED,008/101] gccrs: forever-stack: Fix basic get logic

Message ID 20240130121026.807464-11-arthur.cohen@embecosm.com
State Committed
Commit 446ab9b265554b8e20ff386466f119fcf9e11093
Headers
Series [COMMITTED,001/101] gccrs: Add visibility to trait item |

Commit Message

Arthur Cohen Jan. 30, 2024, 12:06 p.m. UTC
  From: Arthur Cohen <arthur.cohen@embecosm.com>

gcc/rust/ChangeLog:

	* resolve/rust-forever-stack.h: Improve resolve_path API.
	* resolve/rust-forever-stack.hxx: Likewise and fix implementation.
---
 gcc/rust/resolve/rust-forever-stack.h   | 19 +++++++------
 gcc/rust/resolve/rust-forever-stack.hxx | 38 ++++++++++++-------------
 2 files changed, 29 insertions(+), 28 deletions(-)
  

Patch

diff --git a/gcc/rust/resolve/rust-forever-stack.h b/gcc/rust/resolve/rust-forever-stack.h
index 7ee08491987..349d0971f61 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -473,7 +473,7 @@  public:
    * @return a valid option with the NodeId if the path is present in the
    *         current map, an empty one otherwise.
    */
-  tl::optional<NodeId> resolve_path (const AST::SimplePath &path);
+  template <typename P> tl::optional<NodeId> resolve_path (const P &path);
 
   std::string as_debug_string ();
 
@@ -550,18 +550,19 @@  private:
 
   /* Helper types and functions for `resolve_path` */
 
-  using SegIterator = std::vector<AST::SimplePathSegment>::const_iterator;
+  template <typename S>
+  using SegIterator = typename std::vector<S>::const_iterator;
 
   Node &find_closest_module (Node &starting_point);
 
-  tl::optional<SegIterator>
-  find_starting_point (const std::vector<AST::SimplePathSegment> &segments,
-		       Node &starting_point);
+  template <typename S>
+  tl::optional<SegIterator<S>>
+  find_starting_point (const std::vector<S> &segments, Node &starting_point);
 
-  tl::optional<Node &>
-  resolve_segments (Node &starting_point,
-		    const std::vector<AST::SimplePathSegment> &segments,
-		    SegIterator iterator);
+  template <typename S>
+  tl::optional<Node &> resolve_segments (Node &starting_point,
+					 const std::vector<S> &segments,
+					 SegIterator<S> iterator);
 };
 
 } // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx
index 5acdf06c770..806745eb908 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -208,15 +208,8 @@  ForeverStack<N>::update_cursor (Node &new_cursor)
 }
 
 template <Namespace N>
-tl::optional<NodeId>
-ForeverStack<N>::get (const Identifier &name)
-{
-  return tl::nullopt;
-}
-
-template <>
 inline tl::optional<NodeId>
-ForeverStack<Namespace::Macros>::get (const Identifier &name)
+ForeverStack<N>::get (const Identifier &name)
 {
   tl::optional<NodeId> resolved_node = tl::nullopt;
 
@@ -226,9 +219,9 @@  ForeverStack<Namespace::Macros>::get (const Identifier &name)
 
     return candidate.map_or (
       [&resolved_node] (NodeId found) {
-	// macro resolving does not need to care about various ribs - they are
-	// available from all contexts if defined in the current scope, or an
-	// outermore one. so if we do have a candidate, we can return it
+	// for most namespaces, we do not need to care about various ribs - they
+	// are available from all contexts if defined in the current scope, or
+	// an outermore one. so if we do have a candidate, we can return it
 	// directly and stop iterating
 	resolved_node = found;
 
@@ -278,9 +271,9 @@  ForeverStack<N>::find_closest_module (Node &starting_point)
 
 /* If a the given condition is met, emit an error about misused leading path
  * segments */
+template <typename S>
 static inline bool
-check_leading_kw_at_start (const AST::SimplePathSegment &segment,
-			   bool condition)
+check_leading_kw_at_start (const S &segment, bool condition)
 {
   if (condition)
     rust_error_at (
@@ -297,9 +290,10 @@  check_leading_kw_at_start (const AST::SimplePathSegment &segment,
 // `super` segment, we go back to the cursor's parent until we reach the
 // correct one or the root.
 template <Namespace N>
-tl::optional<std::vector<AST::SimplePathSegment>::const_iterator>
-ForeverStack<N>::find_starting_point (
-  const std::vector<AST::SimplePathSegment> &segments, Node &starting_point)
+template <typename S>
+tl::optional<typename std::vector<S>::const_iterator>
+ForeverStack<N>::find_starting_point (const std::vector<S> &segments,
+				      Node &starting_point)
 {
   auto iterator = segments.begin ();
 
@@ -357,10 +351,11 @@  ForeverStack<N>::find_starting_point (
 }
 
 template <Namespace N>
+template <typename S>
 tl::optional<typename ForeverStack<N>::Node &>
 ForeverStack<N>::resolve_segments (
-  Node &starting_point, const std::vector<AST::SimplePathSegment> &segments,
-  std::vector<AST::SimplePathSegment>::const_iterator iterator)
+  Node &starting_point, const std::vector<S> &segments,
+  typename std::vector<S>::const_iterator iterator)
 {
   auto *current_node = &starting_point;
   for (; !is_last (iterator, segments); iterator++)
@@ -407,9 +402,14 @@  ForeverStack<N>::resolve_segments (
 }
 
 template <Namespace N>
+template <typename P>
 tl::optional<NodeId>
-ForeverStack<N>::resolve_path (const AST::SimplePath &path)
+ForeverStack<N>::resolve_path (const P &path)
 {
+  // if there's only one segment, we just use `get`
+  if (path.get_segments ().size () == 1)
+    return get (path.get_final_segment ().as_string ());
+
   auto starting_point = cursor ();
   auto &segments = path.get_segments ();