diff options
author | Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> | 2025-03-24 18:31:12 +0100 |
---|---|---|
committer | P-E-P <32375388+P-E-P@users.noreply.github.com> | 2025-03-27 17:29:15 +0000 |
commit | 9c4e2a7814fcf8889258e028a4c0d4cdc960f6b9 (patch) | |
tree | ac17ba9164dd4f1a601d71890da3b459224f880e /gcc | |
parent | 29cace33c167fd22cf91f3f2f982e70f082db69f (diff) | |
download | gcc-9c4e2a7814fcf8889258e028a4c0d4cdc960f6b9.zip gcc-9c4e2a7814fcf8889258e028a4c0d4cdc960f6b9.tar.gz gcc-9c4e2a7814fcf8889258e028a4c0d4cdc960f6b9.tar.bz2 |
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>
Diffstat (limited to 'gcc')
-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 b4808e2..d5f85b7 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 95e1eea..946aef2 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 44318d1..f96a1d7 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); |