https://gcc.gnu.org/g:652d87e62adf8f910321b023881c1bfa6eefc7d3

commit r17-3097-g652d87e62adf8f910321b023881c1bfa6eefc7d3
Author: Owen Avery <[email protected]>
Date:   Sun Jul 12 10:42:59 2026 -0400

    gccrs: Improve super segment resolution
    
    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]>

Diff:
---
 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(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 1b654c952caf..e901ddbca1c2 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 3c9c6a3d9a76..f5af7b3fa670 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 000000000000..0c3615f715b3
--- /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;
+    }
+}

Reply via email to