From: Arthur Cohen Date: Tue, 24 Mar 2026 12:57:56 +0000 (+0100) Subject: gccrs: nr: Finish moving all segment resolution methods to NRCtx X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a858ece3b7c9408e2d3045e53ebe5b36d34856a3;p=thirdparty%2Fgcc.git 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 --git a/gcc/rust/resolve/rust-forever-stack.h b/gcc/rust/resolve/rust-forever-stack.h index 242b588a394..c28828fda35 100644 --- a/gcc/rust/resolve/rust-forever-stack.h +++ b/gcc/rust/resolve/rust-forever-stack.h @@ -868,16 +868,6 @@ public: std::function insert_segment_resolution, std::vector &collect_errors); - tl::optional resolve_segments ( - Node &starting_point, const std::vector &segments, - SegIterator iterator, - std::function insert_segment_resolution, - std::vector &collect_errors); - - tl::optional 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 e3cd5b7add3..9f1a2cdb563 100644 --- a/gcc/rust/resolve/rust-forever-stack.hxx +++ b/gcc/rust/resolve/rust-forever-stack.hxx @@ -526,147 +526,6 @@ ForeverStack::find_starting_point ( return iterator; } -template -tl::optional::Node &> -ForeverStack::resolve_segments ( - Node &starting_point, const std::vector &segments, - typename std::vector::const_iterator iterator, - std::function insert_segment_resolution, - std::vector &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> 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 -ForeverStack::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 -tl::optional -ForeverStack::resolve_final_segment (Node &final_node, std::string &seg_name, - bool is_lower_self) -{ - return final_node.rib.get (seg_name); -} - template tl::optional::DfsResult> ForeverStack::dfs (ForeverStack::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 6f18115baec..f58f130a15c 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)...); } - /** - * 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 - tl::optional resolve_path ( - ForeverStack &stack, const ResolutionPath &path, ResolutionMode mode, - std::function insert_segment_resolution, - std::vector &collect_errors); - - template - tl::optional resolve_path ( - ForeverStack &stack, const ResolutionPath &path, ResolutionMode mode, - std::function insert_segment_resolution, - std::vector &collect_errors, NodeId starting_point_id); - - /* TODO: Make private? */ - template - tl::optional resolve_path ( - ForeverStack &stack, const ResolutionPath &path, ResolutionMode mode, - std::function insert_segment_resolution, - std::vector &collect_errors, - std::reference_wrapper::Node> starting_point); - - /* If declared with #[prelude_import], the current standard library module */ - tl::optional 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 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 + tl::optional resolve_path ( + ForeverStack &stack, const ResolutionPath &path, ResolutionMode mode, + std::function insert_segment_resolution, + std::vector &collect_errors); + + template + tl::optional resolve_path ( + ForeverStack &stack, const ResolutionPath &path, ResolutionMode mode, + std::function insert_segment_resolution, + std::vector &collect_errors, NodeId starting_point_id); + + template + tl::optional resolve_path ( + ForeverStack &stack, const ResolutionPath &path, ResolutionMode mode, + std::function insert_segment_resolution, + std::vector &collect_errors, + std::reference_wrapper::Node> starting_point); + + template + tl::optional::Node &> resolve_segments ( + ForeverStack &stack, typename ForeverStack::Node &starting_point, + const std::vector &segments, + typename ForeverStack::SegIterator iterator, + std::function insert_segment_resolution, + std::vector &collect_errors); + + template + tl::optional + resolve_final_segment (ForeverStack &stack, + typename ForeverStack::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 resolved_nodes; }; diff --git a/gcc/rust/resolve/rust-name-resolution-context.hxx b/gcc/rust/resolve/rust-name-resolution-context.hxx index a5fc4965a5d..28c7dcccfb7 100644 --- a/gcc/rust/resolve/rust-name-resolution-context.hxx +++ b/gcc/rust/resolve/rust-name-resolution-context.hxx @@ -17,6 +17,7 @@ // . #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 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 +tl::optional::Node &> +NameResolutionContext::resolve_segments ( + ForeverStack &stack, typename ForeverStack::Node &starting_point, + const std::vector &segments, + typename ForeverStack::SegIterator iterator, + std::function insert_segment_resolution, + std::vector &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::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 +NameResolutionContext::resolve_final_segment ( + ForeverStack &stack, + typename ForeverStack::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 +tl::optional +NameResolutionContext::resolve_final_segment ( + ForeverStack &stack, typename ForeverStack::Node &final_node, + std::string &seg_name, bool is_lower_self) +{ + return final_node.rib.get (seg_name); +} + } // namespace Resolver2_0 } // namespace Rust