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