diff options
author | Owen Avery <powerboat9.gamer@gmail.com> | 2025-02-04 05:02:38 -0500 |
---|---|---|
committer | CohenArthur <arthur.cohen@embecosm.com> | 2025-02-17 09:08:38 +0000 |
commit | 681805f7eeaf0ff15045892d289f7e4fe0ea589c (patch) | |
tree | adac45cdcd8d675e82340461d7a907288f3c2427 /gcc/rust | |
parent | de2446d5766e98b23e1aaaea0890b157b2d565d5 (diff) | |
download | gcc-681805f7eeaf0ff15045892d289f7e4fe0ea589c.zip gcc-681805f7eeaf0ff15045892d289f7e4fe0ea589c.tar.gz gcc-681805f7eeaf0ff15045892d289f7e4fe0ea589c.tar.bz2 |
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')
-rw-r--r-- | gcc/rust/resolve/rust-forever-stack.hxx | 60 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 25 |
2 files changed, 56 insertions, 29 deletions
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx index a628c61..39c623c 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 = ¤t_node->parent.value (); } current_node = &child.value (); diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc index 59cac8d..5f988a96 100644 --- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc @@ -294,6 +294,8 @@ Late::visit (AST::TypePath &type) // maybe we can overload `resolve_path<Namespace::Types>` to only do // typepath-like path resolution? that sounds good + DefaultResolver::visit (type); + // take care of only simple cases // TODO: remove this? rust_assert (!type.has_opening_scope_resolution_op ()); @@ -302,14 +304,23 @@ Late::visit (AST::TypePath &type) // TODO: make sure typepath-like path resolution (?) is working auto resolved = ctx.resolve_path (type.get_segments (), Namespace::Types); - if (resolved.has_value ()) - ctx.map_usage (Usage (type.get_node_id ()), - Definition (resolved->get_node_id ())); - else - rust_error_at (type.get_locus (), "could not resolve type path %qs", - type.as_string ().c_str ()); + if (!resolved.has_value ()) + { + if (!ctx.lookup (type.get_segments ().front ()->get_node_id ())) + rust_error_at (type.get_locus (), "could not resolve type path %qs", + type.as_string ().c_str ()); + return; + } - DefaultResolver::visit (type); + if (resolved->is_ambiguous ()) + { + rust_error_at (type.get_locus (), ErrorCode::E0659, "%qs is ambiguous", + type.as_string ().c_str ()); + return; + } + + ctx.map_usage (Usage (type.get_node_id ()), + Definition (resolved->get_node_id ())); } void |