diff options
author | Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> | 2025-03-24 18:31:12 +0100 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2025-03-31 21:07:17 +0200 |
commit | 45bd8bef02cb144f92119256f9f13d739e259b73 (patch) | |
tree | 5799efb8cb12809d12f08b3a59846785c7698cb3 | |
parent | 3ef5915e5f56c04f2e70638eaa46f0baa2a1c388 (diff) | |
download | gcc-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.cc | 17 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-forever-stack.h | 4 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-forever-stack.hxx | 29 |
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); |