From f835da9e51934d99e97ae5a355e3f00838aad64d Mon Sep 17 00:00:00 2001 From: Owen Avery Date: Mon, 11 Aug 2025 13:44:25 -0400 Subject: [PATCH] Improve handling of non-final path segments gcc/rust/ChangeLog: * resolve/rust-forever-stack.hxx (ForeverStack::resolve_segments): Remove usage of optional reference, allow non-final path segments to resolve to types even outside the type namespace, and allow resolution to progress past non-final path segments which resolve to modules. gcc/testsuite/ChangeLog: * rust/compile/use_3.rs: New test. Signed-off-by: Owen Avery --- gcc/rust/resolve/rust-forever-stack.hxx | 21 ++++++++++++++------- gcc/testsuite/rust/compile/use_3.rs | 10 ++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/rust/compile/use_3.rs diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx index 1ed87b3d55b4..848f5e61522b 100644 --- a/gcc/rust/resolve/rust-forever-stack.hxx +++ b/gcc/rust/resolve/rust-forever-stack.hxx @@ -531,7 +531,7 @@ ForeverStack::resolve_segments ( || seg.is_lower_self_seg ())) return tl::nullopt; - tl::optional::Node &> child = tl::nullopt; + tl::optional> child = tl::nullopt; /* * On every iteration this loop either @@ -583,10 +583,17 @@ ForeverStack::resolve_segments ( break; } - if (N == Namespace::Types) + auto rib_lookup = current_node->rib.get (seg.as_string ()); + if (rib_lookup && !rib_lookup->is_ambiguous ()) { - auto rib_lookup = current_node->rib.get (seg.as_string ()); - if (rib_lookup && !rib_lookup->is_ambiguous ()) + if (Analysis::Mappings::get () + .lookup_glob_container (rib_lookup->get_node_id ()) + .has_value ()) + { + child = dfs_node (root, rib_lookup->get_node_id ()).value (); + break; + } + else { insert_segment_resolution (outer_seg, rib_lookup->get_node_id ()); @@ -611,9 +618,9 @@ ForeverStack::resolve_segments ( current_node = ¤t_node->parent.value (); } - // if child didn't contain a value - // the while loop above should have return'd or kept looping - current_node = &child.value (); + // if child didn't point to a value + // the while loop above would have returned or kept looping + current_node = &child->get (); insert_segment_resolution (outer_seg, current_node->id); } diff --git a/gcc/testsuite/rust/compile/use_3.rs b/gcc/testsuite/rust/compile/use_3.rs new file mode 100644 index 000000000000..2cfe38f47b26 --- /dev/null +++ b/gcc/testsuite/rust/compile/use_3.rs @@ -0,0 +1,10 @@ +mod intrinsic { + pub fn foo() {} +} + +pub mod a { + pub fn b() { + use crate::intrinsic; + intrinsic::foo(); + } +}