https://gcc.gnu.org/g:93375f97c22a045a810ee9afceee9ad7ca24a782
commit r17-1079-g93375f97c22a045a810ee9afceee9ad7ca24a782 Author: Arthur Cohen <[email protected]> Date: Mon Mar 23 12:52:00 2026 +0100 gccrs: nr: Do first part of path resolution in types NS gcc/rust/ChangeLog: * resolve/rust-name-resolution-context.hxx: Do segment resolution in types NS for more correctness and correct behavior when later resolving paths that use imports and/or modules. Diff: --- gcc/rust/resolve/rust-name-resolution-context.hxx | 96 ++++++++++++++--------- 1 file changed, 58 insertions(+), 38 deletions(-) diff --git a/gcc/rust/resolve/rust-name-resolution-context.hxx b/gcc/rust/resolve/rust-name-resolution-context.hxx index ae89126153de..a5fc4965a5d6 100644 --- a/gcc/rust/resolve/rust-name-resolution-context.hxx +++ b/gcc/rust/resolve/rust-name-resolution-context.hxx @@ -16,6 +16,7 @@ // along with GCC; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. +#include "optional.h" #include "rust-name-resolution-context.h" /** @@ -196,53 +197,72 @@ NameResolutionContext::resolve_path ( return tl::nullopt; } - return stack - .resolve_segments (starting_point.get (), segments, iterator, - insert_segment_resolution, collect_errors) - .and_then ([&segments, &insert_segment_resolution, - &stack] (typename ForeverStack<N>::Node &final_node) - -> tl::optional<Rib::Definition> { - // leave resolution within impl blocks to type checker - if (final_node.rib.kind == Rib::Kind::TraitOrImpl) - return tl::nullopt; + // We do the first part of path resolution exclusively in the types NS - this + // gives us a node in which to resolve the last segment of the path. - auto &seg = segments.back (); - std::string seg_name = seg.name; + // We take our starting point and then get the equivalent Node from the Types + // NS - since it existed in whatever namespace we are right now, we assume it + // exists in the types NS. + auto types_starting_point + = types.dfs_node (types.root, starting_point.get ().id); - tl::optional<Rib::Definition> res - = stack.resolve_final_segment (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); + // TODO: Add a method for converting a node between namespaces? Make all of + // the starting point stuff return a NodeId rather than a Node&? And take a + // NodeId as a starting point rather than a Node? - if (N == Namespace::Types && !res) + auto node + = types.resolve_segments (types_starting_point.value (), segments, iterator, + insert_segment_resolution, collect_errors); + + if (!node) + return tl::nullopt; + + // This node now represents the Node which *should* contain the definition + // used by the last segment. We now get the equivalent Node from this + // namespace after finding it in the types NS. + auto final_node_id = node.value ().id; + auto final_node = stack.dfs_node (stack.root, final_node_id).value (); + + // leave resolution within impl blocks to type checker + if (final_node.rib.kind == Rib::Kind::TraitOrImpl) + return tl::nullopt; + + auto &seg = segments.back (); + std::string seg_name = seg.name; + + tl::optional<Rib::Definition> res + = stack.resolve_final_segment (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); + + if (N == Namespace::Types && !res) + { + // HACK: check for a module after we check the language prelude + for (auto &kv : final_node.children) { - // HACK: check for a module after we check the language prelude - for (auto &kv : final_node.children) + auto &link = kv.first; + + if (link.path.map_or ( + [&seg_name] (Identifier path) { + auto &path_str = path.as_string (); + return path_str == seg_name; + }, + false)) { - auto &link = kv.first; - - if (link.path.map_or ( - [&seg_name] (Identifier path) { - auto &path_str = path.as_string (); - return path_str == seg_name; - }, - false)) - { - insert_segment_resolution (Usage (seg.node_id), - Definition (kv.second.id)); - return Rib::Definition::NonShadowable (kv.second.id); - } + insert_segment_resolution (Usage (seg.node_id), + Definition (kv.second.id)); + return Rib::Definition::NonShadowable (kv.second.id); } } + } - if (res && !res->is_ambiguous ()) - insert_segment_resolution (Usage (seg.node_id), - Definition (res->get_node_id ())); + if (res && !res->is_ambiguous ()) + insert_segment_resolution (Usage (seg.node_id), + Definition (res->get_node_id ())); - return res; - }); + return res; } } // namespace Resolver2_0
