From: Pierre-Emmanuel Patry <[email protected]>

We often split the segments and opening scope appart and lose the global
path information.

gcc/rust/ChangeLog:

        * ast/rust-ast-builder.cc: Update function name to use parent.
        * ast/rust-ast-collector.cc (TokenCollector::visit): Likewise.
        * ast/rust-path.cc (TypePath::as_string): Likewise.
        (PathInExpression::as_string): Likewise.
        (TypePath::as_simple_path): Likewise.
        (TypePath::make_debug_string): Likewise.
        (Path::as_string): Use getters instead.
        * hir/rust-ast-lower.cc (ASTLowerPathInExpression::visit):
        Likewise.
        * expand/rust-derive-clone.cc (DeriveClone::clone_enum_identifier):
        Likewise.
        (DeriveClone::clone_enum_tuple): Likewise.
        (DeriveClone::clone_enum_struct): Likewise.
        * hir/rust-ast-lower-type.cc (ASTLowerTypePath::visit): Likewise.
        * ast/rust-ast.h: Remove fields and use a parent raw path class.
        * ast/rust-path.h: Likewise. Remove util path conversion function.
        * resolve/rust-early-name-resolver-2.0.cc (Early::resolve_glob_import):
        Remove utilpath construct.
        * resolve/rust-early-name-resolver-2.0.h: Likewise.
        * resolve/rust-forever-stack.h (class ResolutionPath): Move and rename
        Segment class from here...
        (struct ResolutionPathSegment): ... to here.
        * resolve/rust-forever-stack.hxx: Accept new segment class name.
        * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Remove
        UtilPath.
        * resolve/rust-name-resolution-context.h: Use RawPath in set_path
        instead of UtilPath. Remove path specific resolve_path functions.
        * resolve/rust-name-resolution-context.hxx: Remove UtilPath.
        * ast/rust-raw-path.h: New file.

Signed-off-by: Pierre-Emmanuel Patry <[email protected]>
---
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/b5a3478ced507b162f2b760c78f9f0687cf82eda

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/5044

 gcc/rust/ast/rust-ast-builder.cc              |  2 +-
 gcc/rust/ast/rust-ast-collector.cc            |  4 +-
 gcc/rust/ast/rust-ast.h                       | 40 ++------
 gcc/rust/ast/rust-path.cc                     | 12 +--
 gcc/rust/ast/rust-path.h                      | 96 +++++--------------
 gcc/rust/ast/rust-raw-path.h                  | 64 +++++++++++++
 gcc/rust/expand/rust-derive-clone.cc          | 10 +-
 gcc/rust/hir/rust-ast-lower-type.cc           |  2 +-
 gcc/rust/hir/rust-ast-lower.cc                |  2 +-
 .../resolve/rust-early-name-resolver-2.0.cc   |  9 +-
 .../resolve/rust-early-name-resolver-2.0.h    | 12 +--
 gcc/rust/resolve/rust-forever-stack.h         | 44 ++++-----
 gcc/rust/resolve/rust-forever-stack.hxx       |  9 +-
 .../resolve/rust-late-name-resolver-2.0.cc    |  5 +-
 .../resolve/rust-name-resolution-context.h    | 63 ++++--------
 .../resolve/rust-name-resolution-context.hxx  | 14 +--
 16 files changed, 167 insertions(+), 221 deletions(-)
 create mode 100644 gcc/rust/ast/rust-raw-path.h

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 44b6a721f..3f5b7a721 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -660,7 +660,7 @@ Builder::new_type_param (
              }
 
            TypePath p (std::move (segments), path.get_locus (),
-                       path.has_opening_scope_resolution_op ());
+                       path.has_opening_scope_resolution ());
 
            type_param_bounds.emplace_back (new TraitBound (
              std::move (p), tb.get_locus (), tb.is_in_parens (),
diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index 97a0df706..9ee48b27d 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -610,7 +610,7 @@ TokenCollector::visit (PathInExpression &path)
        return;
       }
 
-    if (path.opening_scope_resolution ())
+    if (path.has_opening_scope_resolution ())
       push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
 
     visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
@@ -757,7 +757,7 @@ TokenCollector::visit (TypePath &path)
   // Syntax:
   //    `::`? TypePathSegment (`::` TypePathSegment)*
   describe_node (std::string ("TypePath"), [this, &path] () {
-    if (path.has_opening_scope_resolution_op ())
+    if (path.has_opening_scope_resolution ())
       push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
 
     visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index d2d76edb0..5000b3281 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -29,6 +29,7 @@
 #include "rust-cloneable.h"
 #include "rust-ast-identifier.h"
 #include "rust-util-path.h"
+#include "rust-raw-path.h"
 
 namespace Rust {
 // TODO: remove typedefs and make actual types for these
@@ -338,10 +339,8 @@ public:
 };
 
 // A simple path without generic or type arguments
-class SimplePath
+class SimplePath : public RawPath<SimplePathSegment>
 {
-  bool opening_scope_resolution;
-  std::vector<SimplePathSegment> segments;
   location_t locus;
   NodeId node_id;
 
@@ -350,14 +349,13 @@ public:
   explicit SimplePath (std::vector<SimplePathSegment> path_segments,
                       bool has_opening_scope_resolution = false,
                       location_t locus = UNDEF_LOCATION)
-    : opening_scope_resolution (has_opening_scope_resolution),
-      segments (std::move (path_segments)), locus (locus),
-      node_id (Analysis::Mappings::get ().get_next_node_id ())
+    : RawPath (std::move (path_segments), has_opening_scope_resolution),
+      locus (locus), node_id (Analysis::Mappings::get ().get_next_node_id ())
   {}
 
   explicit SimplePath (Identifier ident)
-    : opening_scope_resolution (false),
-      segments ({SimplePathSegment (ident.as_string (), ident.get_locus ())}),
+    : RawPath ({SimplePathSegment (ident.as_string (), ident.get_locus ())},
+              false),
       locus (ident.get_locus ()),
       node_id (Analysis::Mappings::get ().get_next_node_id ())
   {}
@@ -368,16 +366,8 @@ public:
     return SimplePath (std::vector<SimplePathSegment> ());
   }
 
-  // Returns whether the SimplePath is empty, i.e. has path segments.
-  bool is_empty () const { return segments.empty (); }
-
   const std::string as_string () const;
 
-  bool has_opening_scope_resolution () const
-  {
-    return opening_scope_resolution;
-  }
-
   location_t get_locus () const { return locus; }
   NodeId get_node_id () const { return node_id; }
 
@@ -400,24 +390,6 @@ public:
       = {AST::SimplePathSegment (std::move (str), locus)};
     return SimplePath (std::move (single_segments), false, locus);
   }
-
-  const std::vector<SimplePathSegment> &get_segments () const
-  {
-    return segments;
-  }
-
-  std::vector<SimplePathSegment> &get_segments () { return segments; }
-
-  const SimplePathSegment &get_final_segment () const
-  {
-    return segments.back ();
-  }
-
-  UtilPath<SimplePathSegment> as_util_path () const
-  {
-    return UtilPath<SimplePathSegment> (get_segments (),
-                                       has_opening_scope_resolution ());
-  }
 };
 
 // path-to-string inverse comparison operator
diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc
index e8b885cbc..c5a2bb1cc 100644
--- a/gcc/rust/ast/rust-path.cc
+++ b/gcc/rust/ast/rust-path.cc
@@ -144,7 +144,7 @@ Path::as_string () const
 
   std::string str;
 
-  for (const auto &segment : segments)
+  for (const auto &segment : get_segments ())
     str += segment.as_string () + "::";
 
   // basically a hack - remove last two characters of string (remove final ::)
@@ -200,7 +200,7 @@ PathInExpression::as_string () const
 {
   std::string str;
 
-  if (has_opening_scope_resolution)
+  if (has_opening_scope_resolution ())
     str = "::";
 
   return str + Path::as_string ();
@@ -227,7 +227,7 @@ TypePath::as_string () const
    * literalised */
   std::string str;
 
-  if (has_opening_scope_resolution)
+  if (has_opening_scope_resolution ())
     str = "::";
 
   for (const auto &segment : segments)
@@ -262,8 +262,8 @@ TypePath::as_simple_path () const
                                    segment->get_locus ());
     }
 
-  return SimplePath (std::move (simple_segments), has_opening_scope_resolution,
-                    locus);
+  return SimplePath (std::move (simple_segments),
+                    has_opening_scope_resolution (), locus);
 }
 
 std::string
@@ -278,7 +278,7 @@ TypePath::make_debug_string () const
       if (segment != nullptr && !segment->is_lang_item ()
          && !segment->is_error ())
        {
-         if (!output.empty () || has_opening_scope_resolution_op ())
+         if (!output.empty () || has_opening_scope_resolution ())
            output.append ("::");
          output.append (segment->get_ident_segment ().as_string ());
        }
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 37f5c19c9..6a867ce6f 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -26,7 +26,7 @@
 #include "rust-hir-map.h"
 #include "rust-mapping-common.h"
 #include "rust-system.h"
-#include "system.h"
+#include "rust-raw-path.h"
 
 namespace Rust {
 namespace AST {
@@ -640,7 +640,7 @@ public:
 
 // AST node representing a pattern that involves a "path" - abstract base
 // class
-class Path : public Pattern
+class Path : public Pattern, public RawPath<PathExprSegment>
 {
 public:
   enum class Kind
@@ -649,20 +649,20 @@ public:
     Regular,
   };
 
-  Path (std::vector<PathExprSegment> segments)
-    : segments (std::move (segments)), lang_item (tl::nullopt),
-      kind (Kind::Regular)
+  Path (std::vector<PathExprSegment> segments, bool opening_scope_resolution)
+    : RawPath (std::move (segments), opening_scope_resolution),
+      lang_item (tl::nullopt), kind (Kind::Regular)
   {}
 
   Path (LangItem::Kind lang_item)
-    : segments ({}), lang_item (lang_item), kind (Kind::LangItem)
+    : RawPath ({}, false), lang_item (lang_item), kind (Kind::LangItem)
   {}
 
   // Returns whether path has segments.
   bool has_segments () const
   {
     rust_assert (kind == Kind::Regular);
-    return !segments.empty ();
+    return !is_empty ();
   }
 
   /* Converts path segments to their equivalent SimplePath segments if
@@ -674,7 +674,7 @@ public:
   bool is_single_segment () const
   {
     rust_assert (kind == Kind::Regular);
-    return segments.size () == 1;
+    return get_segments ().size () == 1;
   }
 
   std::string as_string () const override;
@@ -703,7 +703,6 @@ public:
   Path::Kind get_path_kind () { return kind; }
 
 protected:
-  std::vector<PathExprSegment> segments;
   tl::optional<LangItem::Kind> lang_item;
 
   Path::Kind kind;
@@ -714,7 +713,6 @@ protected:
 class PathInExpression : public Path, public ExprWithoutBlock
 {
   std::vector<Attribute> outer_attrs;
-  bool has_opening_scope_resolution;
   location_t locus;
   NodeId _node_id;
 
@@ -727,16 +725,15 @@ public:
   PathInExpression (std::vector<PathExprSegment> path_segments,
                    std::vector<Attribute> outer_attrs, location_t locus,
                    bool has_opening_scope_resolution = false)
-    : Path (std::move (path_segments)), outer_attrs (std::move (outer_attrs)),
-      has_opening_scope_resolution (has_opening_scope_resolution),
-      locus (locus), _node_id (Analysis::Mappings::get ().get_next_node_id ()),
+    : Path (std::move (path_segments), has_opening_scope_resolution),
+      outer_attrs (std::move (outer_attrs)), locus (locus),
+      _node_id (Analysis::Mappings::get ().get_next_node_id ()),
       marked_for_strip (false)
   {}
 
   PathInExpression (LangItem::Kind lang_item,
                    std::vector<Attribute> outer_attrs, location_t locus)
-    : Path (lang_item), outer_attrs (std::move (outer_attrs)),
-      has_opening_scope_resolution (false), locus (locus),
+    : Path (lang_item), outer_attrs (std::move (outer_attrs)), locus (locus),
       _node_id (Analysis::Mappings::get ().get_next_node_id ()),
       marked_for_strip (false)
   {}
@@ -761,7 +758,7 @@ public:
      * public. Have to pass in opening scope resolution as parent class has no
      * access to it.
      */
-    return convert_to_simple_path (has_opening_scope_resolution);
+    return convert_to_simple_path (has_opening_scope_resolution ());
   }
 
   std::unique_ptr<PathInExpression> reconstruct () const
@@ -773,7 +770,7 @@ public:
 
     auto *new_path
       = new PathInExpression (std::move (new_segments), outer_attrs, locus,
-                             has_opening_scope_resolution);
+                             has_opening_scope_resolution ());
 
     return std::unique_ptr<PathInExpression> (new_path);
   }
@@ -785,11 +782,6 @@ public:
   void mark_for_strip () override { marked_for_strip = true; }
   bool is_marked_for_strip () const override { return marked_for_strip; }
 
-  bool opening_scope_resolution () const
-  {
-    return has_opening_scope_resolution;
-  }
-
   NodeId get_node_id () const override { return _node_id; }
 
   const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; 
}
@@ -800,23 +792,11 @@ public:
     outer_attrs = std::move (new_attrs);
   }
 
-  PathExprSegment &get_final_segment () { return get_segments ().back (); }
-  const PathExprSegment &get_final_segment () const
-  {
-    return get_segments ().back ();
-  }
-
   Expr::Kind get_expr_kind () const override
   {
     return Expr::Kind::PathInExpression;
   }
 
-  UtilPath<PathExprSegment> as_util_path () const
-  {
-    return UtilPath<PathExprSegment> (get_segments (),
-                                     has_opening_scope_resolution);
-  }
-
 protected:
   /* Use covariance to implement clone function as returning this object
    * rather than base */
@@ -1261,10 +1241,9 @@ public:
   }
 };
 
-class TypePath : public TypeNoBounds
+class TypePath : public TypeNoBounds,
+                public RawPath<std::unique_ptr<TypePathSegment>>
 {
-  bool has_opening_scope_resolution;
-  std::vector<std::unique_ptr<TypePathSegment>> segments;
   location_t locus;
 
 protected:
@@ -1276,18 +1255,11 @@ protected:
   }
   TypePath *reconstruct_impl () const override
   {
-    return new TypePath (reconstruct_vec (segments), locus,
-                        has_opening_scope_resolution);
+    return new TypePath (reconstruct_vec (get_segments ()), locus,
+                        has_opening_scope_resolution ());
   }
 
 public:
-  /* Returns whether the TypePath has an opening scope resolution operator
-   * (i.e. is global path or crate-relative path, not module-relative) */
-  bool has_opening_scope_resolution_op () const
-  {
-    return has_opening_scope_resolution;
-  }
-
   // Returns whether the TypePath is in an invalid state.
   bool is_error () const { return segments.empty (); }
 
@@ -1302,22 +1274,21 @@ public:
   TypePath (std::vector<std::unique_ptr<TypePathSegment>> segments,
            location_t locus, bool has_opening_scope_resolution = false)
     : TypeNoBounds (),
-      has_opening_scope_resolution (has_opening_scope_resolution),
-      segments (std::move (segments)), locus (locus)
+      RawPath (std::move (segments), has_opening_scope_resolution),
+      locus (locus)
   {}
 
   TypePath (LangItem::Kind lang_item,
            std::vector<std::unique_ptr<TypePathSegment>> segments,
            location_t locus, bool has_opening_scope_resolution = false)
     : TypeNoBounds (),
-      has_opening_scope_resolution (has_opening_scope_resolution),
-      segments (std::move (segments)), locus (locus)
+      RawPath (std::move (segments), has_opening_scope_resolution),
+      locus (locus)
   {}
 
   // Copy constructor with vector clone
   TypePath (TypePath const &other)
-    : TypeNoBounds (other),
-      has_opening_scope_resolution (other.has_opening_scope_resolution),
+    : TypeNoBounds (other), RawPath ({}, other.has_opening_scope_resolution 
()),
       locus (other.locus)
   {
     segments.reserve (other.segments.size ());
@@ -1329,7 +1300,7 @@ public:
   TypePath &operator= (TypePath const &other)
   {
     TypeNoBounds::operator= (other);
-    has_opening_scope_resolution = other.has_opening_scope_resolution;
+    opening_scope_resolution = other.has_opening_scope_resolution ();
     locus = other.locus;
 
     segments.reserve (other.segments.size ());
@@ -1362,25 +1333,9 @@ public:
 
   void accept_vis (ASTVisitor &vis) override;
 
-  // TODO: this seems kinda dodgy
-  std::vector<std::unique_ptr<TypePathSegment>> &get_segments ()
-  {
-    return segments;
-  }
-  const std::vector<std::unique_ptr<TypePathSegment>> &get_segments () const
-  {
-    return segments;
-  }
-
   size_t get_num_segments () const { return segments.size (); }
 
   Type::Kind get_type_kind () const override { return Type::Kind::TypePath; }
-
-  UtilPath<std::unique_ptr<TypePathSegment>> as_util_path () const
-  {
-    return UtilPath<std::unique_ptr<TypePathSegment>> (
-      get_segments (), has_opening_scope_resolution_op ());
-  }
 };
 
 struct QualifiedPathType
@@ -1502,7 +1457,8 @@ public:
                             std::vector<PathExprSegment> path_segments,
                             std::vector<Attribute> outer_attrs,
                             location_t locus)
-    : Path (std::move (path_segments)), outer_attrs (std::move (outer_attrs)),
+    : Path (std::move (path_segments), false),
+      outer_attrs (std::move (outer_attrs)),
       path_type (std::move (qual_path_type)), locus (locus),
       _node_id (Analysis::Mappings::get ().get_next_node_id ())
   {}
diff --git a/gcc/rust/ast/rust-raw-path.h b/gcc/rust/ast/rust-raw-path.h
new file mode 100644
index 000000000..d653f5312
--- /dev/null
+++ b/gcc/rust/ast/rust-raw-path.h
@@ -0,0 +1,64 @@
+// Copyright (C) 2026 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-system.h"
+
+#ifndef RUST_RAW_PATH_H
+#define RUST_RAW_PATH_H
+
+namespace Rust {
+
+template <typename Segment> class RawPath
+{
+protected:
+  std::vector<Segment> segments;
+  bool opening_scope_resolution;
+
+public:
+  RawPath (std::vector<Segment> segments, bool opening_scope_resolution)
+    : segments (std::move (segments)),
+      opening_scope_resolution (opening_scope_resolution)
+  {}
+
+  /* Returns whether the RawPath has an opening scope resolution operator
+   * (i.e. is global path or crate-relative path, not module-relative) */
+  bool has_opening_scope_resolution () const
+  {
+    return opening_scope_resolution;
+  }
+
+  const std::vector<Segment> &get_segments () const { return segments; }
+  std::vector<Segment> &get_segments () { return segments; }
+
+  bool is_empty () const { return segments.empty (); }
+
+  Segment &get_final_segment ()
+  {
+    rust_assert (!is_empty ());
+    return get_segments ().back ();
+  }
+  const Segment &get_final_segment () const
+  {
+    rust_assert (!is_empty ());
+    return get_segments ().back ();
+  }
+};
+
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/expand/rust-derive-clone.cc 
b/gcc/rust/expand/rust-derive-clone.cc
index f71592b29..4406164e7 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -171,12 +171,12 @@ DeriveClone::clone_enum_identifier (PathInExpression 
variant_path,
   auto pattern = std::unique_ptr<Pattern> (new ReferencePattern (
     std::unique_ptr<Pattern> (new PathInExpression (
       variant_path.get_segments (), {}, variant_path.get_locus (),
-      variant_path.opening_scope_resolution ())),
+      variant_path.has_opening_scope_resolution ())),
     false, false, loc));
   auto expr = std::unique_ptr<Expr> (
     new PathInExpression (variant_path.get_segments (), {},
                          variant_path.get_locus (),
-                         variant_path.opening_scope_resolution ()));
+                         variant_path.has_opening_scope_resolution ()));
 
   return builder.match_case (std::move (pattern), std::move (expr));
 }
@@ -211,14 +211,14 @@ DeriveClone::clone_enum_tuple (PathInExpression 
variant_path,
     std::unique_ptr<Pattern> (new TupleStructPattern (
       PathInExpression (variant_path.get_segments (), {},
                        variant_path.get_locus (),
-                       variant_path.opening_scope_resolution ()),
+                       variant_path.has_opening_scope_resolution ()),
       std::move (pattern_items))),
     false, false, loc));
 
   auto expr = builder.call (std::unique_ptr<Expr> (new PathInExpression (
                              variant_path.get_segments (), {},
                              variant_path.get_locus (),
-                             variant_path.opening_scope_resolution ())),
+                             variant_path.has_opening_scope_resolution ())),
                            std::move (cloned_patterns));
 
   return builder.match_case (std::move (pattern), std::move (expr));
@@ -291,7 +291,7 @@ DeriveClone::clone_enum_struct (PathInExpression 
variant_path,
   PathInExpression new_path (variant_path.get_segments (),
                             variant_path.get_outer_attrs (),
                             variant_path.get_locus (),
-                            variant_path.opening_scope_resolution ());
+                            variant_path.has_opening_scope_resolution ());
 
   auto expr = std::unique_ptr<Expr> (
     new StructExprStructFields (new_path, std::move (cloned_fields), loc));
diff --git a/gcc/rust/hir/rust-ast-lower-type.cc 
b/gcc/rust/hir/rust-ast-lower-type.cc
index a41d49706..cca5cb30c 100644
--- a/gcc/rust/hir/rust-ast-lower-type.cc
+++ b/gcc/rust/hir/rust-ast-lower-type.cc
@@ -145,7 +145,7 @@ ASTLowerTypePath::visit (AST::TypePath &path)
   translated
     = new HIR::TypePath (std::move (mapping), std::move (translated_segments),
                         path.get_locus (),
-                        path.has_opening_scope_resolution_op ());
+                        path.has_opening_scope_resolution ());
 }
 
 HIR::QualifiedPathInType *
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index 7167a0afb..152ff81ea 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/hir/rust-ast-lower.cc
@@ -492,7 +492,7 @@ ASTLowerPathInExpression::visit (AST::PathInExpression 
&expr)
 
   translated = new HIR::PathInExpression (mapping, std::move (path_segments),
                                          expr.get_locus (),
-                                         expr.opening_scope_resolution ());
+                                         expr.has_opening_scope_resolution ());
 }
 
 HIR::QualifiedPathType
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 6a7100127..7e61b2c88 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -111,12 +111,9 @@ Early::import_resolution_mode (const AST::SimplePath &path)
 bool
 Early::resolve_glob_import (NodeId use_dec_id, TopLevel::ImportKind &&glob)
 {
-  auto path = UtilPath<AST::SimplePathSegment> (
-    glob.to_resolve.get_segments (),
-    glob.to_resolve.has_opening_scope_resolution ());
-  auto resolved
-    = ctx.resolve_path (path, import_resolution_mode (glob.to_resolve),
-                       Namespace::Types);
+  auto resolved = ctx.resolve_path (glob.to_resolve,
+                                   import_resolution_mode (glob.to_resolve),
+                                   Namespace::Types);
   if (!resolved.has_value ())
     return false;
 
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 610c6df39..cc0e3689d 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
@@ -220,8 +220,6 @@ private:
   std::vector<NameResolutionContext::NamespacedDefinition>
   resolve_path_in_all_ns (const P &path)
   {
-    auto &segments = path.get_segments ();
-    bool opening_scope_resolution = path.has_opening_scope_resolution ();
     auto mode = import_resolution_mode (path);
 
     std::vector<NameResolutionContext::NamespacedDefinition> resolved;
@@ -235,15 +233,11 @@ private:
          resolved.emplace_back (new_def);
        };
 
-    auto util_path = UtilPath<
-      typename std::remove_reference_t<decltype (segments)>::value_type> (
-      segments, opening_scope_resolution);
-
-    ctx.resolve_path (util_path, mode, value_errors, Namespace::Values)
+    ctx.resolve_path (path, mode, value_errors, Namespace::Values)
       .map (resolved_fn);
-    ctx.resolve_path (util_path, mode, type_errors, Namespace::Types)
+    ctx.resolve_path (path, mode, type_errors, Namespace::Types)
       .map (resolved_fn);
-    ctx.resolve_path (util_path, mode, macro_errors, Namespace::Macros)
+    ctx.resolve_path (path, mode, macro_errors, Namespace::Macros)
       .map (resolved_fn);
 
     if (!value_errors.empty () && !type_errors.empty ()
diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index c45159bd6..70ea85be5 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -402,13 +402,25 @@ enum class ResolutionMode
   FromExtern, // extern prelude
 };
 
-class ResolutionPath
+struct ResolutionPathSegment
+{
+  std::string name;
+  NodeId node_id;
+  location_t locus;
+
+  bool is_super_path_seg () const { return name.compare ("super") == 0; }
+  bool is_crate_path_seg () const { return name.compare ("crate") == 0; }
+  bool is_lower_self_seg () const { return name.compare ("self") == 0; }
+  bool is_big_self_seg () const { return name.compare ("Self") == 0; }
+};
+
+class ResolutionPath : public RawPath<ResolutionPathSegment>
 {
 public:
   template <typename T>
   ResolutionPath (const std::vector<T> &segments_in,
                  bool opening_scope_resolution, NodeId node_id)
-    : opening_scope_resolution (opening_scope_resolution), node_id (node_id)
+    : RawPath ({}, opening_scope_resolution), node_id (node_id)
   {
     segments.clear ();
     segments.reserve (segments_in.size ());
@@ -424,7 +436,7 @@ public:
 
        auto &seg = unwrap_type_segment (outer_seg);
 
-       Segment new_seg;
+       ResolutionPathSegment new_seg;
        new_seg.name = seg.as_string ();
        new_seg.node_id = unwrap_segment_node_id (outer_seg);
        new_seg.locus = seg.get_locus ();
@@ -432,27 +444,17 @@ public:
       }
   }
 
-  ResolutionPath () : opening_scope_resolution (false), node_id 
(UNKNOWN_NODEID)
-  {}
-
-  struct Segment
-  {
-    std::string name;
-    NodeId node_id;
-    location_t locus;
-
-    bool is_super_path_seg () const { return name.compare ("super") == 0; }
-    bool is_crate_path_seg () const { return name.compare ("crate") == 0; }
-    bool is_lower_self_seg () const { return name.compare ("self") == 0; }
-    bool is_big_self_seg () const { return name.compare ("Self") == 0; }
-  };
+  ResolutionPath () : RawPath ({}, false), node_id (UNKNOWN_NODEID) {}
 
   tl::optional<std::pair<LangItem::Kind, NodeId>> get_lang_prefix () const
   {
     return lang_prefix;
   }
 
-  const std::vector<Segment> &get_segments () const { return segments; }
+  const std::vector<ResolutionPathSegment> &get_segments () const
+  {
+    return segments;
+  }
 
   bool has_opening_scope_resolution () const
   {
@@ -480,8 +482,6 @@ public:
 
 private:
   tl::optional<std::pair<LangItem::Kind, NodeId>> lang_prefix;
-  std::vector<Segment> segments;
-  bool opening_scope_resolution;
   NodeId node_id;
 };
 
@@ -781,12 +781,12 @@ public:
   /* Helper types and functions for `resolve_path` */
 
   using SegIterator =
-    typename std::vector<ResolutionPath::Segment>::const_iterator;
+    typename std::vector<ResolutionPathSegment>::const_iterator;
 
   Node &find_closest_module (Node &starting_point);
 
   tl::optional<SegIterator>
-  find_starting_point (const UtilPath<ResolutionPath::Segment> &path,
+  find_starting_point (const RawPath<ResolutionPathSegment> &path,
                       std::reference_wrapper<Node> &starting_point,
                       std::function<void (Usage, Definition, Namespace)>
                         insert_segment_resolution,
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 715e04e2e..5f4397aca 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -447,8 +447,7 @@ ForeverStack<N>::find_closest_module (Node &starting_point)
  * segments */
 static inline bool
 check_leading_kw_at_start (std::vector<Error> &collect_errors,
-                          const ResolutionPath::Segment &segment,
-                          bool condition)
+                          const ResolutionPathSegment &segment, bool condition)
 {
   if (condition)
     collect_errors.emplace_back (
@@ -464,9 +463,9 @@ check_leading_kw_at_start (std::vector<Error> 
&collect_errors,
 // `super` segment, we go back to the cursor's parent until we reach the
 // correct one or the root.
 template <Namespace N>
-tl::optional<typename std::vector<ResolutionPath::Segment>::const_iterator>
+tl::optional<typename std::vector<ResolutionPathSegment>::const_iterator>
 ForeverStack<N>::find_starting_point (
-  const UtilPath<ResolutionPath::Segment> &path,
+  const RawPath<ResolutionPathSegment> &path,
   std::reference_wrapper<Node> &starting_point,
   std::function<void (Usage, Definition, Namespace)> insert_segment_resolution,
   std::vector<Error> &collect_errors)
@@ -494,7 +493,7 @@ ForeverStack<N>::find_starting_point (
 
       if (seg.is_crate_path_seg ())
        {
-         if (path.has_opening_scope ())
+         if (path.has_opening_scope_resolution ())
            {
              collect_errors.emplace_back (seg.locus, ErrorCode::E0433,
                                           "global paths cannot start with %qs",
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 6bf67f145..487f12a3c 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -628,10 +628,7 @@ Late::visit (AST::Visibility &vis)
        }
     }
 
-  auto util_path
-    = UtilPath<AST::SimplePathSegment> (path.get_segments (),
-                                       path.has_opening_scope_resolution ());
-  auto res = ctx.resolve_path (util_path, mode, Namespace::Types);
+  auto res = ctx.resolve_path (path, mode, Namespace::Types);
 
   if (!res.has_value ())
     {
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h 
b/gcc/rust/resolve/rust-name-resolution-context.h
index cddf01ddb..155c20711 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -687,12 +687,12 @@ public:
     ResolutionBuilder (NameResolutionContext &ctx) : ctx (&ctx) {}
 
     template <typename S>
-    void set_path (const UtilPath<S> &util_path, NodeId node_id)
+    void set_path (const RawPath<S> &new_path, NodeId node_id)
     {
-      path = ResolutionPath (util_path.get_segments (),
-                            util_path.has_opening_scope (), node_id);
+      path = ResolutionPath (new_path.get_segments (),
+                            new_path.has_opening_scope_resolution (), node_id);
       mode = ResolutionMode::Normal;
-      if (util_path.has_opening_scope ())
+      if (new_path.has_opening_scope_resolution ())
        {
          if (get_rust_edition () == Edition::E2015)
            mode = ResolutionMode::FromRoot;
@@ -703,28 +703,28 @@ public:
     }
 
     template <typename S>
-    void set_path (const UtilPath<S> &util_path, NodeId node_id,
+    void set_path (const RawPath<S> &new_path, NodeId node_id,
                   ResolutionMode mode)
     {
-      path = ResolutionPath (util_path.get_segments (),
-                            util_path.has_opening_scope (), node_id);
+      path = ResolutionPath (new_path.get_segments (),
+                            new_path.has_opening_scope_resolution (), node_id);
       this->mode = mode;
       has_path_set = true;
     }
 
     void set_path (const AST::SimplePath &path)
     {
-      set_path (path.as_util_path (), path.get_node_id ());
+      set_path (path, path.get_node_id ());
     }
 
     void set_path (const AST::PathInExpression &path)
     {
-      set_path (path.as_util_path (), path.get_node_id ());
+      set_path (path, path.get_node_id ());
     }
 
     void set_path (const AST::TypePath &path)
     {
-      set_path (path.as_util_path (), path.get_node_id ());
+      set_path (path, path.get_node_id ());
     }
 
     void set_mode (ResolutionMode mode) { this->mode = mode; }
@@ -785,7 +785,7 @@ public:
 
   template <typename S, typename... Args>
   tl::optional<NamespacedDefinition>
-  resolve_path (const UtilPath<S> &path, ResolutionMode mode,
+  resolve_path (const RawPath<S> &path, ResolutionMode mode,
                tl::optional<std::vector<Error> &> collect_errors,
                Namespace ns_first, Args... ns_args)
   {
@@ -799,7 +799,7 @@ public:
 
   template <typename S, typename... Args>
   tl::optional<NamespacedDefinition>
-  resolve_path (const UtilPath<S> &path,
+  resolve_path (const RawPath<S> &path,
                tl::optional<std::vector<Error> &> collect_errors,
                Namespace ns_first, Args... ns_args)
   {
@@ -814,7 +814,7 @@ public:
 
   template <typename S, typename... Args>
   tl::optional<NamespacedDefinition>
-  resolve_path (const UtilPath<S> &path, Namespace ns_first, Args... ns_args)
+  resolve_path (const RawPath<S> &path, Namespace ns_first, Args... ns_args)
   {
     ResolutionBuilder builder (*this);
     builder.set_path (path, UNKNOWN_NODEID);
@@ -825,8 +825,8 @@ public:
 
   template <typename S, typename... Args>
   tl::optional<NamespacedDefinition>
-  resolve_path (const UtilPath<S> &path, ResolutionMode mode,
-               Namespace ns_first, Args... ns_args)
+  resolve_path (const RawPath<S> &path, ResolutionMode mode, Namespace 
ns_first,
+               Args... ns_args)
   {
     ResolutionBuilder builder (*this);
     builder.set_path (path, UNKNOWN_NODEID, mode);
@@ -835,35 +835,6 @@ public:
     return builder.resolve ();
   }
 
-  template <typename... Args>
-  tl::optional<NamespacedDefinition> resolve_path (const AST::SimplePath &path,
-                                                  Args &&...args)
-  {
-    auto util_path
-      = UtilPath<AST::SimplePathSegment> (path.get_segments (),
-                                         path.has_opening_scope_resolution ());
-    return resolve_path (util_path, std::forward<Args> (args)...);
-  }
-
-  template <typename... Args>
-  tl::optional<NamespacedDefinition>
-  resolve_path (const AST::PathInExpression &path, Args &&...args)
-  {
-    auto util_path
-      = UtilPath<AST::PathExprSegment> (path.get_segments (),
-                                       path.opening_scope_resolution ());
-    return resolve_path (util_path, std::forward<Args> (args)...);
-  }
-
-  template <typename... Args>
-  tl::optional<NamespacedDefinition> resolve_path (const AST::TypePath &path,
-                                                  Args &&...args)
-  {
-    auto util_path = UtilPath<std::unique_ptr<AST::TypePathSegment>> (
-      path.get_segments (), path.has_opening_scope_resolution_op ());
-    return resolve_path (util_path, std::forward<Args> (args)...);
-  }
-
   /*
    * Merge a name resolution context within another one at a given location.
    *
@@ -906,7 +877,7 @@ private:
   bool
   should_search_prelude (const typename ForeverStack<N>::Node *current_node,
                         const typename ForeverStack<N>::SegIterator &iterator,
-                        const std::vector<ResolutionPath::Segment> &segments);
+                        const std::vector<ResolutionPathSegment> &segments);
 
   /**
    * Resolve a path to its definition
@@ -944,7 +915,7 @@ private:
   tl::optional<typename ForeverStack<N>::Node &>
   resolve_segments (ForeverStack<N> &stack,
                    typename ForeverStack<N>::Node &starting_point,
-                   const UtilPath<ResolutionPath::Segment> &path,
+                   const RawPath<ResolutionPathSegment> &path,
                    typename ForeverStack<N>::SegIterator iterator,
                    std::function<void (Usage, Definition, Namespace)>
                      insert_segment_resolution,
diff --git a/gcc/rust/resolve/rust-name-resolution-context.hxx 
b/gcc/rust/resolve/rust-name-resolution-context.hxx
index 568e9b705..9741e5da1 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.hxx
+++ b/gcc/rust/resolve/rust-name-resolution-context.hxx
@@ -33,7 +33,7 @@ bool
 NameResolutionContext::should_search_prelude (
   const typename ForeverStack<N>::Node *current_node,
   const typename ForeverStack<N>::SegIterator &iterator,
-  const std::vector<ResolutionPath::Segment> &segments)
+  const std::vector<ResolutionPathSegment> &segments)
 {
   // Check whether the current_node is a root node
   if (current_node->is_root ())
@@ -190,12 +190,9 @@ NameResolutionContext::resolve_path (
     }
 
   auto iterator = segments.begin ();
-  auto util_path
-    = UtilPath<ResolutionPath::Segment> (segments,
-                                        path.has_opening_scope_resolution ());
   if (can_descend)
     {
-      if (auto res = stack.find_starting_point (util_path, starting_point,
+      if (auto res = stack.find_starting_point (path, starting_point,
                                                insert_segment_resolution,
                                                collect_errors))
        iterator = *res;
@@ -216,9 +213,8 @@ NameResolutionContext::resolve_path (
   // gives us a node in which to resolve the last segment of the path.
 
   // nodes are shared between stacks
-  auto node
-    = resolve_segments (types, starting_point.get (), util_path, iterator,
-                       insert_segment_resolution, collect_errors);
+  auto node = resolve_segments (types, starting_point.get (), path, iterator,
+                               insert_segment_resolution, collect_errors);
 
   if (!node)
     return tl::nullopt;
@@ -252,7 +248,7 @@ template <Namespace N>
 tl::optional<typename ForeverStack<N>::Node &>
 NameResolutionContext::resolve_segments (
   ForeverStack<N> &stack, typename ForeverStack<N>::Node &starting_point,
-  const UtilPath<ResolutionPath::Segment> &path,
+  const RawPath<ResolutionPathSegment> &path,
   typename ForeverStack<N>::SegIterator iterator,
   std::function<void (Usage, Definition, Namespace)> insert_segment_resolution,
   std::vector<Error> &collect_errors)

base-commit: a87ec0b8756f69aac7da755eb923e7da41fe7cd3
-- 
2.56.0

Reply via email to