[COMMITTED 081/141] gccrs: nr2.0: Resolve paths which start with Self

arthur.cohen@embecosm.com arthur.cohen@embecosm.com
Mon Mar 24 12:45:04 GMT 2025


From: Owen Avery <powerboat9.gamer@gmail.com>

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>
---
 gcc/rust/resolve/rust-forever-stack.hxx       | 60 ++++++++++++-------
 .../resolve/rust-late-name-resolver-2.0.cc    | 25 +++++---
 gcc/testsuite/rust/compile/nr2/exclude        | 35 -----------
 3 files changed, 56 insertions(+), 64 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx
index b51da51948f..d2020554f74 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 ();
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 c134ca03336..7253deb42d9 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
diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude
index 6f6280d3b66..a400378f071 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -1,8 +1,6 @@
-bounds1.rs
 break-rust2.rs
 canonical_paths1.rs
 cfg1.rs
-closure_no_type_anno.rs
 complex-path1.rs
 const-issue1440.rs
 const_generics_3.rs
@@ -11,29 +9,19 @@ const_generics_7.rs
 derive_macro1.rs
 expected_type_args2.rs
 feature_rust_attri0.rs
-format_args_basic_expansion.rs
 generic-default1.rs
 generics3.rs
 generics4.rs
 generics5.rs
-generics6.rs
 generics9.rs
 issue-1130.rs
 issue-1173.rs
-issue-1272.rs
-issue-1447.rs
 issue-1483.rs
-issue-1725-1.rs
-issue-1725-2.rs
 issue-1786.rs
-issue-1893.rs
 issue-1901.rs
 issue-1981.rs
-issue-2036.rs
 issue-2043.rs
-issue-2142.rs
 issue-2330.rs
-issue-2479.rs
 issue-2723-1.rs
 issue-2723-2.rs
 issue-2775.rs
@@ -43,11 +31,9 @@ issue-850.rs
 issue-855.rs
 iterators1.rs
 lookup_err1.rs
-macros/mbe/macro20.rs
 macros/mbe/macro40.rs
 macros/mbe/macro43.rs
 macros/mbe/macro44.rs
-macros/mbe/macro54.rs
 macros/mbe/macro6.rs
 macros/mbe/macro_use1.rs
 method2.rs
@@ -57,7 +43,6 @@ nested_macro_use1.rs
 nested_macro_use2.rs
 nested_macro_use3.rs
 not_find_value_in_scope.rs
-pattern-struct.rs
 privacy4.rs
 privacy5.rs
 privacy8.rs
@@ -83,15 +68,10 @@ v0-mangle2.rs
 while_break_expr.rs
 exhaustiveness2.rs
 issue-3139-2.rs
-issue-3032-1.rs
-issue-3032-2.rs
-iflet.rs
 issue-3033.rs
 issue-3009.rs
 issue-2953-2.rs
-issue-1773.rs
 issue-2905-2.rs
-issue-2907.rs
 issue-2423.rs
 issue-266.rs
 additional-trait-bounds2.rs
@@ -103,22 +83,7 @@ derive_macro6.rs
 issue-2987.rs
 issue-3139-1.rs
 issue-3139-3.rs
-issue-1019.rs
-issue-1034.rs
-issue-2019-1.rs
-issue-2019-2.rs
-issue-2019-3.rs
-issue-2105.rs
-issue-2190-1.rs
-issue-2190-2.rs
-issue-2304.rs
-issue-2747.rs
-issue-2953-1.rs
-issue-3030.rs
-traits12.rs
-try-trait.rs
 derive-debug1.rs
-issue-3382.rs
 derive-default1.rs
 issue-3402-1.rs
 for-loop1.rs
-- 
2.45.2



More information about the Gcc-rust mailing list