From: Pierre-Emmanuel Patry Date: Mon, 24 Mar 2025 17:31:12 +0000 (+0100) Subject: Resolve module final self segment in use decls X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9c4e2a7814fcf8889258e028a4c0d4cdc960f6b9;p=thirdparty%2Fgcc.git 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 --- 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 b4808e2508b..d5f85b7d16c 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 95e1eead275..946aef2fb48 100644 --- a/gcc/rust/resolve/rust-forever-stack.h +++ b/gcc/rust/resolve/rust-forever-stack.h @@ -795,6 +795,10 @@ private: SegIterator iterator, std::function insert_segment_resolution); + tl::optional 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 44318d1b298..f96a1d775d6 100644 --- a/gcc/rust/resolve/rust-forever-stack.hxx +++ b/gcc/rust/resolve/rust-forever-stack.hxx @@ -594,6 +594,26 @@ ForeverStack::resolve_segments ( return *current_node; } +template <> +inline tl::optional +ForeverStack::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 +tl::optional +ForeverStack::resolve_final_segment (Node &final_node, std::string &seg_name, + bool is_lower_self) +{ + return final_node.rib.get (seg_name); +} + template template tl::optional @@ -643,12 +663,13 @@ ForeverStack::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 res = final_node.rib.get (seg_name); - + tl::optional 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);