[COMMITTED 39/77] gccrs: Improve super segment resolution

[email protected]
Newsgroups gmane.comp.gcc.patches,gmane.comp.gcc.rust
Message-ID <[email protected]>
From: Owen Avery <[email protected]>

gcc/rust/ChangeLog:

	* resolve/rust-forever-stack.hxx
	(ForeverStack::find_starting_point): Handle a final super
	segment and super segments after a lowercase self segment.
	* resolve/rust-name-resolution-context.hxx
	(NameResolutionContext::resolve_path): Handle cases where
	find_starting_point resolves the final segment.

gcc/testsuite/ChangeLog:

	* rust/compile/name_resolution29.rs: New test.

Signed-off-by: Owen Avery <[email protected]>
---
 gcc/rust/resolve/rust-forever-stack.hxx           | 12 ++++++++----
 gcc/rust/resolve/rust-name-resolution-context.hxx |  9 +++++++++
 gcc/testsuite/rust/compile/name_resolution29.rs   | 10 ++++++++++
 3 files changed, 27 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/name_resolution29.rs

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx
index 1b654c952ca..e901ddbca1c 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -463,10 +463,14 @@ ForeverStack<N>::find_starting_point (
 {
   auto iterator = segments.begin ();
 
-  for (; !is_last (iterator, segments); iterator++)
+  for (; iterator != segments.end (); iterator++)
     {
       auto &seg = *iterator;
 
+      // don't include a final self segment
+      if (is_last (iterator, segments) && seg.is_lower_self_seg ())
+	break;
+
       bool is_self_or_crate
 	= seg.is_crate_path_seg () || seg.is_lower_self_seg ();
 
@@ -487,12 +491,12 @@ ForeverStack<N>::find_starting_point (
 	}
       if (seg.is_lower_self_seg ())
 	{
-	  // insert segment resolution and exit
+	  // insert segment resolution
 	  starting_point = find_closest_module (starting_point);
 	  insert_segment_resolution (Usage (seg.node_id),
 				     Definition (starting_point.get ().id), N);
-	  iterator++;
-	  break;
+	  // don't exit -- we could see some "super" segments
+	  continue;
 	}
       if (seg.is_super_path_seg ())
 	{
diff --git a/gcc/rust/resolve/rust-name-resolution-context.hxx b/gcc/rust/resolve/rust-name-resolution-context.hxx
index 3c9c6a3d9a7..f5af7b3fa67 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.hxx
+++ b/gcc/rust/resolve/rust-name-resolution-context.hxx
@@ -198,6 +198,15 @@ NameResolutionContext::resolve_path (
 	iterator = *res;
       else
 	return tl::nullopt;
+
+      // if find_starting_point used all segments, return early
+      if (iterator == segments.end ())
+	{
+	  if (N == Namespace::Types)
+	    return Rib::Definition::NonShadowable (starting_point.get ().id);
+	  else
+	    return tl::nullopt;
+	}
     }
 
   // We do the first part of path resolution exclusively in the types NS - this
diff --git a/gcc/testsuite/rust/compile/name_resolution29.rs b/gcc/testsuite/rust/compile/name_resolution29.rs
new file mode 100644
index 00000000000..0c3615f715b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/name_resolution29.rs
@@ -0,0 +1,10 @@
+// { dg-additional-options "-w" }
+#![feature(no_core)]
+#![no_core]
+
+mod a {
+    mod b {
+        pub (in super::super) struct S;
+        pub (in self::super::super) struct T;
+    }
+}
-- 
2.50.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.