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 = ¤t_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 = ¤t_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 = ¤t_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 = ¤t_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