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]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/7cc595fafff3bafc115127818a0b890194ff84c0

The commit has NOT been mentioned in any issue.

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4699

 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 1b654c952..e901ddbca 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 3c9c6a3d9..f5af7b3fa 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 000000000..0c3615f71
--- /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;
+    }
+}

base-commit: 2a1f86dfe935a7309198cc9b66f45d62b9b37cf9
-- 
2.54.0

Reply via email to