aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve/rust-forever-stack.hxx
diff options
context:
space:
mode:
authorOwen Avery <powerboat9.gamer@gmail.com>2025-02-04 05:02:38 -0500
committerArthur Cohen <arthur.cohen@embecosm.com>2025-03-24 13:07:06 +0100
commit0da1380d6637758977a467473a659a1a5b80c72a (patch)
tree0b018f6c30252b57b7c8e5695f0b70a053794c93 /gcc/rust/resolve/rust-forever-stack.hxx
parent3e589260b4edf4a1eeb0934de65a8c5d0c6c73b3 (diff)
downloadgcc-0da1380d6637758977a467473a659a1a5b80c72a.zip
gcc-0da1380d6637758977a467473a659a1a5b80c72a.tar.gz
gcc-0da1380d6637758977a467473a659a1a5b80c72a.tar.bz2
gccrs: nr2.0: Resolve paths which start with Self
gcc/rust/ChangeLog: * resolve/rust-forever-stack.hxx (ForeverStack::find_starting_point): Be more careful about applying ForeverStack::find_closest_module. (ForeverStack::resolve_segments): Allow traversal into parent nodes when not in a module node or root node, which ForeverStack::find_starting_point previously made moot through use of ForeverStack::find_closest_module. Also, when a child node lookup fails when resolving in the type namespace, attempt a rib lookup as a fallback. * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Avoid throwing a resolution error for type paths when the typechecker may be able to finish the resolution. Also, throw an error when a resolution is ambiguous. gcc/testsuite/ChangeLog: * rust/compile/nr2/exclude: Remove entries. Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
Diffstat (limited to 'gcc/rust/resolve/rust-forever-stack.hxx')
-rw-r--r--gcc/rust/resolve/rust-forever-stack.hxx60
1 files changed, 38 insertions, 22 deletions
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx
index b51da51..d202055 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -381,13 +381,6 @@ ForeverStack<N>::find_starting_point (
{
auto iterator = segments.begin ();
- // If we need to do path segment resolution, then we start
- // at the closest module. In order to resolve something like `foo::bar!()`, we
- // need to get back to the surrounding module, and look for a child module
- // named `foo`.
- if (segments.size () > 1)
- starting_point = find_closest_module (starting_point);
-
for (; !is_last (iterator, segments); iterator++)
{
auto &outer_seg = *iterator;
@@ -416,12 +409,14 @@ ForeverStack<N>::find_starting_point (
if (seg.is_lower_self_seg ())
{
// insert segment resolution and exit
+ starting_point = find_closest_module (starting_point);
insert_segment_resolution (outer_seg, starting_point.get ().id);
iterator++;
break;
}
if (seg.is_super_path_seg ())
{
+ starting_point = find_closest_module (starting_point);
if (starting_point.get ().is_root ())
{
rust_error_at (seg.get_locus (), ErrorCode::E0433,
@@ -469,27 +464,48 @@ ForeverStack<N>::resolve_segments (
tl::optional<typename ForeverStack<N>::Node &> child = tl::nullopt;
- for (auto &kv : current_node->children)
+ while (true)
{
- auto &link = kv.first;
+ 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 (link.path.map_or (
- [&str] (Identifier path) {
- auto &path_str = path.as_string ();
- return str == path_str;
- },
- false))
+ if (child.has_value ())
{
- child = kv.second;
break;
}
- }
- if (!child.has_value ())
- {
- rust_error_at (seg.get_locus (), ErrorCode::E0433,
- "failed to resolve path segment %qs", str.c_str ());
- return tl::nullopt;
+ if (N == Namespace::Types)
+ {
+ auto rib_lookup = current_node->rib.get (seg.as_string ());
+ if (rib_lookup && !rib_lookup->is_ambiguous ())
+ {
+ insert_segment_resolution (outer_seg,
+ rib_lookup->get_node_id ());
+ return tl::nullopt;
+ }
+ }
+
+ if (!is_start (iterator, segments)
+ || current_node->rib.kind == Rib::Kind::Module
+ || current_node->is_root ())
+ {
+ return tl::nullopt;
+ }
+
+ current_node = &current_node->parent.value ();
}
current_node = &child.value ();