https://gcc.gnu.org/g:a858ece3b7c9408e2d3045e53ebe5b36d34856a3
commit r17-1867-ga858ece3b7c9408e2d3045e53ebe5b36d34856a3 Author: Arthur Cohen <[email protected]> Date: Tue Mar 24 13:57:56 2026 +0100 gccrs: nr: Finish moving all segment resolution methods to NRCtx 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. Diff: --- gcc/rust/resolve/rust-forever-stack.h | 10 -- gcc/rust/resolve/rust-forever-stack.hxx | 141 -------------------- gcc/rust/resolve/rust-name-resolution-context.h | 75 ++++++----- gcc/rust/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 242b588a3945..c28828fda35e 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 e3cd5b7add3b..9f1a2cdb563d 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 6f18115baecd..f58f130a15c5 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 a5fc4965a5d6..28c7dcccfb7c 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
