https://gcc.gnu.org/g:45bd8bef02cb144f92119256f9f13d739e259b73

commit r15-9095-g45bd8bef02cb144f92119256f9f13d739e259b73
Author: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>
Date:   Mon Mar 24 18:31:12 2025 +0100

    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.pa...@embecosm.com>

Diff:
---
 gcc/rust/resolve/rust-early-name-resolver-2.0.cc | 17 ++++++++++----
 gcc/rust/resolve/rust-forever-stack.h            |  4 ++++
 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 492a665f43e9..afaca1f71f03 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 2a4c7348728b..d86212073b8d 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 a6e0b30a57b1..fbe537d3b41d 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);

Reply via email to