aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>2025-03-24 18:31:12 +0100
committerArthur Cohen <arthur.cohen@embecosm.com>2025-03-31 21:07:17 +0200
commit45bd8bef02cb144f92119256f9f13d739e259b73 (patch)
tree5799efb8cb12809d12f08b3a59846785c7698cb3
parent3ef5915e5f56c04f2e70638eaa46f0baa2a1c388 (diff)
downloadgcc-45bd8bef02cb144f92119256f9f13d739e259b73.zip
gcc-45bd8bef02cb144f92119256f9f13d739e259b73.tar.gz
gcc-45bd8bef02cb144f92119256f9f13d739e259b73.tar.bz2
gccrs: Resolve module final self segment in use decls
Lowercase self suffix with path was not resolved properly, this should point to the module right before. gcc/rust/ChangeLog: * resolve/rust-forever-stack.hxx: Add a new specialized function to retrieve the last "real" segment depending on the namespace. * resolve/rust-forever-stack.h: Add new function prototype. * resolve/rust-early-name-resolver-2.0.cc (Early::finalize_rebind_import): Set declared name according to the selected segment, if there is a self suffix in the use declaration then select the previous segment. Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.cc17
-rw-r--r--gcc/rust/resolve/rust-forever-stack.h4
-rw-r--r--gcc/rust/resolve/rust-forever-stack.hxx29
3 files changed, 42 insertions, 8 deletions
diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index 492a665..afaca1f 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -417,10 +417,19 @@ Early::finalize_rebind_import (const Early::ImportPair &mapping)
declared_name = rebind.get_identifier ().as_string ();
locus = rebind.get_identifier ().get_locus ();
break;
- case AST::UseTreeRebind::NewBindType::NONE:
- declared_name = path.get_final_segment ().as_string ();
- locus = path.get_final_segment ().get_locus ();
- break;
+ case AST::UseTreeRebind::NewBindType::NONE: {
+ const auto &segments = path.get_segments ();
+ // We don't want to insert `self` with `use module::self`
+ if (path.get_final_segment ().is_lower_self_seg ())
+ {
+ rust_assert (segments.size () > 1);
+ declared_name = segments[segments.size () - 2].as_string ();
+ }
+ else
+ declared_name = path.get_final_segment ().as_string ();
+ locus = path.get_final_segment ().get_locus ();
+ break;
+ }
case AST::UseTreeRebind::NewBindType::WILDCARD:
rust_unreachable ();
break;
diff --git a/gcc/rust/resolve/rust-forever-stack.h b/gcc/rust/resolve/rust-forever-stack.h
index 2a4c734..d862120 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -795,6 +795,10 @@ private:
SegIterator<S> iterator,
std::function<void (const S &, NodeId)> insert_segment_resolution);
+ tl::optional<Rib::Definition> resolve_final_segment (Node &final_node,
+ std::string &seg_name,
+ bool is_lower_self);
+
/* Helper functions for forward resolution (to_canonical_path, to_rib...) */
struct DfsResult
{
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx
index a6e0b30..fbe537d 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -594,6 +594,26 @@ ForeverStack<N>::resolve_segments (
return *current_node;
}
+template <>
+inline tl::optional<Rib::Definition>
+ForeverStack<Namespace::Types>::resolve_final_segment (Node &final_node,
+ std::string &seg_name,
+ bool is_lower_self)
+{
+ if (is_lower_self)
+ return Rib::Definition::NonShadowable (final_node.id);
+ else
+ return final_node.rib.get (seg_name);
+}
+
+template <Namespace N>
+tl::optional<Rib::Definition>
+ForeverStack<N>::resolve_final_segment (Node &final_node, std::string &seg_name,
+ bool is_lower_self)
+{
+ return final_node.rib.get (seg_name);
+}
+
template <Namespace N>
template <typename S>
tl::optional<Rib::Definition>
@@ -643,12 +663,13 @@ ForeverStack<N>::resolve_path (
if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
return tl::nullopt;
- std::string seg_name
- = unwrap_type_segment (segments.back ()).as_string ();
+ auto &seg = unwrap_type_segment (segments.back ());
+ std::string seg_name = seg.as_string ();
// assuming this can't be a lang item segment
- tl::optional<Rib::Definition> res = final_node.rib.get (seg_name);
-
+ tl::optional<Rib::Definition> res
+ = resolve_final_segment (final_node, seg_name,
+ seg.is_lower_self_seg ());
// Ok we didn't find it in the rib, Lets try the prelude...
if (!res)
res = get_prelude (seg_name);