From: Pierre-Emmanuel Patry <[email protected]>
We used in several places a vector of segment (unspecified segment kind)
but left the opening scope information. This commit introduces a new
class to group both segments and opening scope information in one place.
gcc/rust/ChangeLog:
* ast/rust-ast.h: Add a new function to convert to util path.
* ast/rust-path.h: Likewise.
* resolve/rust-early-name-resolver-2.0.cc (Early::resolve_glob_import):
Create a UtilPath and use it.
* resolve/rust-early-name-resolver-2.0.h: Likewise.
* resolve/rust-forever-stack.h: Change ResolutionPath class to add an
opening_scope_resolution flag to mark extern prelude paths. Add a
getter for that flag.
* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Use a UtilPath.
* resolve/rust-name-resolution-context.h: Change set_path functions
to accept a UtilPath instead of a simple vector or segment.
* util/rust-util-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/61950bcefd1e0aa20ed6dd5a29aca1593c960f79
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/5030
gcc/rust/ast/rust-ast.h | 7 ++
gcc/rust/ast/rust-path.h | 12 ++++
.../resolve/rust-early-name-resolver-2.0.cc | 9 ++-
.../resolve/rust-early-name-resolver-2.0.h | 11 +++-
gcc/rust/resolve/rust-forever-stack.h | 14 +++-
.../resolve/rust-late-name-resolver-2.0.cc | 5 +-
.../resolve/rust-name-resolution-context.h | 64 +++++++++----------
gcc/rust/util/rust-util-path.h | 41 ++++++++++++
8 files changed, 120 insertions(+), 43 deletions(-)
create mode 100644 gcc/rust/util/rust-util-path.h
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 50778bcaf..d2d76edb0 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -28,6 +28,7 @@
#include "rust-keyword-values.h"
#include "rust-cloneable.h"
#include "rust-ast-identifier.h"
+#include "rust-util-path.h"
namespace Rust {
// TODO: remove typedefs and make actual types for these
@@ -411,6 +412,12 @@ public:
{
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.h b/gcc/rust/ast/rust-path.h
index ecb156e90..37f5c19c9 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -811,6 +811,12 @@ public:
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 */
@@ -1369,6 +1375,12 @@ public:
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
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 1422a300d..6a7100127 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -111,9 +111,12 @@ Early::import_resolution_mode (const AST::SimplePath &path)
bool
Early::resolve_glob_import (NodeId use_dec_id, TopLevel::ImportKind &&glob)
{
- auto resolved = ctx.resolve_path (glob.to_resolve.get_segments (),
- import_resolution_mode (glob.to_resolve),
- Namespace::Types);
+ 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);
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 c8cfe3891..610c6df39 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
@@ -221,6 +221,7 @@ private:
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;
@@ -234,11 +235,15 @@ private:
resolved.emplace_back (new_def);
};
- ctx.resolve_path (segments, mode, value_errors, Namespace::Values)
+ 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)
.map (resolved_fn);
- ctx.resolve_path (segments, mode, type_errors, Namespace::Types)
+ ctx.resolve_path (util_path, mode, type_errors, Namespace::Types)
.map (resolved_fn);
- ctx.resolve_path (segments, mode, macro_errors, Namespace::Macros)
+ ctx.resolve_path (util_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 22cb68850..0f9874eb8 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -406,8 +406,9 @@ class ResolutionPath
{
public:
template <typename T>
- ResolutionPath (const std::vector<T> &segments_in, NodeId node_id)
- : node_id (node_id)
+ ResolutionPath (const std::vector<T> &segments_in,
+ bool opening_scope_resolution, NodeId node_id)
+ : opening_scope_resolution (opening_scope_resolution), node_id (node_id)
{
segments.clear ();
segments.reserve (segments_in.size ());
@@ -431,7 +432,8 @@ public:
}
}
- ResolutionPath () : node_id (UNKNOWN_NODEID) {}
+ ResolutionPath () : opening_scope_resolution (false), node_id
(UNKNOWN_NODEID)
+ {}
struct Segment
{
@@ -452,6 +454,11 @@ public:
const std::vector<Segment> &get_segments () const { return segments; }
+ bool has_opening_scope_resolution () const
+ {
+ return opening_scope_resolution;
+ }
+
NodeId get_node_id () const { return node_id; }
std::string as_string () const
@@ -474,6 +481,7 @@ public:
private:
tl::optional<std::pair<LangItem::Kind, NodeId>> lang_prefix;
std::vector<Segment> segments;
+ bool opening_scope_resolution;
NodeId node_id;
};
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 dfcf6b283..6bf67f145 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -628,7 +628,10 @@ Late::visit (AST::Visibility &vis)
}
}
- auto res = ctx.resolve_path (path.get_segments (), mode, Namespace::Types);
+ auto util_path
+ = UtilPath<AST::SimplePathSegment> (path.get_segments (),
+ path.has_opening_scope_resolution ());
+ auto res = ctx.resolve_path (util_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 f9a277ce1..62b31d9b1 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -26,6 +26,7 @@
#include "rust-stacked-contexts.h"
#include "rust-item.h"
#include "rust-name-resolution.h"
+#include "rust-util-path.h"
namespace Rust {
namespace Resolver2_0 {
@@ -686,12 +687,12 @@ public:
ResolutionBuilder (NameResolutionContext &ctx) : ctx (&ctx) {}
template <typename S>
- void set_path (const std::vector<S> &path_segments, NodeId node_id,
- bool has_opening_scope)
+ void set_path (const UtilPath<S> &util_path, NodeId node_id)
{
- path = ResolutionPath (path_segments, node_id);
+ path = ResolutionPath (util_path.get_segments (),
+ util_path.has_opening_scope (), node_id);
mode = ResolutionMode::Normal;
- if (has_opening_scope)
+ if (util_path.has_opening_scope ())
{
if (get_rust_edition () == Edition::E2015)
mode = ResolutionMode::FromRoot;
@@ -702,30 +703,28 @@ public:
}
template <typename S>
- void set_path (const std::vector<S> &path_segments, NodeId node_id,
+ void set_path (const UtilPath<S> &util_path, NodeId node_id,
ResolutionMode mode)
{
- path = ResolutionPath (path_segments, node_id);
+ path = ResolutionPath (util_path.get_segments (),
+ util_path.has_opening_scope (), node_id);
this->mode = mode;
has_path_set = true;
}
void set_path (const AST::SimplePath &path)
{
- set_path (path.get_segments (), path.get_node_id (),
- path.has_opening_scope_resolution ());
+ set_path (path.as_util_path (), path.get_node_id ());
}
void set_path (const AST::PathInExpression &path)
{
- set_path (path.get_segments (), path.get_node_id (),
- path.opening_scope_resolution ());
+ set_path (path.as_util_path (), path.get_node_id ());
}
void set_path (const AST::TypePath &path)
{
- set_path (path.get_segments (), path.get_node_id (),
- path.has_opening_scope_resolution_op ());
+ set_path (path.as_util_path (), path.get_node_id ());
}
void set_mode (ResolutionMode mode) { this->mode = mode; }
@@ -786,12 +785,12 @@ public:
template <typename S, typename... Args>
tl::optional<NamespacedDefinition>
- resolve_path (const std::vector<S> &path_segments, ResolutionMode mode,
+ resolve_path (const UtilPath<S> &path, ResolutionMode mode,
tl::optional<std::vector<Error> &> collect_errors,
Namespace ns_first, Args... ns_args)
{
ResolutionBuilder builder (*this);
- builder.set_path (path_segments, UNKNOWN_NODEID, mode);
+ builder.set_path (path, UNKNOWN_NODEID, mode);
builder.add_namespaces (ns_first, ns_args...);
builder.set_collect_errors (collect_errors);
@@ -800,14 +799,13 @@ public:
template <typename S, typename... Args>
tl::optional<NamespacedDefinition>
- resolve_path (const std::vector<S> &path_segments,
- bool has_opening_scope_resolution,
+ resolve_path (const UtilPath<S> &path,
tl::optional<std::vector<Error> &> collect_errors,
Namespace ns_first, Args... ns_args)
{
ResolutionBuilder builder (*this);
- builder.set_path (path_segments, UNKNOWN_NODEID,
- has_opening_scope_resolution);
+ builder.set_path (path.get_segments (), path.has_opening_scope (),
+ UNKNOWN_NODEID);
builder.add_namespaces (ns_first, ns_args...);
builder.set_collect_errors (collect_errors);
@@ -816,13 +814,10 @@ public:
template <typename S, typename... Args>
tl::optional<NamespacedDefinition>
- resolve_path (const std::vector<S> &path_segments,
- bool has_opening_scope_resolution, Namespace ns_first,
- Args... ns_args)
+ resolve_path (const UtilPath<S> &path, Namespace ns_first, Args... ns_args)
{
ResolutionBuilder builder (*this);
- builder.set_path (path_segments, UNKNOWN_NODEID,
- has_opening_scope_resolution);
+ builder.set_path (path, UNKNOWN_NODEID);
builder.add_namespaces (ns_first, ns_args...);
return builder.resolve ();
@@ -830,11 +825,11 @@ public:
template <typename S, typename... Args>
tl::optional<NamespacedDefinition>
- resolve_path (const std::vector<S> &path_segments, ResolutionMode mode,
+ resolve_path (const UtilPath<S> &path, ResolutionMode mode,
Namespace ns_first, Args... ns_args)
{
ResolutionBuilder builder (*this);
- builder.set_path (path_segments, UNKNOWN_NODEID, mode);
+ builder.set_path (path, UNKNOWN_NODEID, mode);
builder.add_namespaces (ns_first, ns_args...);
return builder.resolve ();
@@ -844,26 +839,29 @@ public:
tl::optional<NamespacedDefinition> resolve_path (const AST::SimplePath &path,
Args &&...args)
{
- return resolve_path (path.get_segments (),
- path.has_opening_scope_resolution (),
- std::forward<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)
{
- return resolve_path (path.get_segments (), path.opening_scope_resolution
(),
- std::forward<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)
{
- return resolve_path (path.get_segments (),
- path.has_opening_scope_resolution_op (),
- std::forward<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)...);
}
/*
diff --git a/gcc/rust/util/rust-util-path.h b/gcc/rust/util/rust-util-path.h
new file mode 100644
index 000000000..f612afd9f
--- /dev/null
+++ b/gcc/rust/util/rust-util-path.h
@@ -0,0 +1,41 @@
+// 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_UTIL_PATH_H
+#define RUST_UTIL_PATH_H
+
+// Simple path container class to keep segments and opening scope flag together
+// whilst keeping the segment type generic.
+//
+// Only meant as a tuple for path elements with a name and a proper type.
+template <typename Segment> struct UtilPath
+{
+ UtilPath (const std::vector<Segment> &segments, bool opening_scope)
+ : segments (segments), opening_scope (opening_scope)
+ {}
+
+ const std::vector<Segment> &segments;
+ bool opening_scope;
+
+ bool has_opening_scope () const { return opening_scope; }
+ const std::vector<Segment> &get_segments () const { return segments; }
+};
+
+#endif
base-commit: 4bad9e6144dd3fe867919aeb75a63e790f985087
--
2.56.0