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; + } +}
