[gccrs COMMIT 4/5] gccrs: Add impl-item-name indexes for method resolution

gerris.rs@gmail.com gerris.rs@gmail.com
Sun Sep 6 19:15:26 GMT 2026


From: Philip Herron <herron.philip@googlemail.com>

gcc/rust/ChangeLog:

	* typecheck/rust-hir-dot-operator.cc: use item name indexes
	* util/rust-hir-map.cc (Mappings::insert_hir_impl_block): new index
	(Mappings::insert_trait_item_mapping): likewise
	* util/rust-hir-map.h: likewise

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: https://github.com/Rust-GCC/gccrs/commit/a004d5ae4dba489341ca2330eb558bd504df5dbe

The commit has NOT been mentioned in any issue.

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4847

 gcc/rust/typecheck/rust-hir-dot-operator.cc | 135 +++++++++-----------
 gcc/rust/util/rust-hir-map.cc               |  59 ++++++++-
 gcc/rust/util/rust-hir-map.h                |  34 +++--
 3 files changed, 138 insertions(+), 90 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.cc b/gcc/rust/typecheck/rust-hir-dot-operator.cc
index a2ecb2649..a680a4aaa 100644
--- a/gcc/rust/typecheck/rust-hir-dot-operator.cc
+++ b/gcc/rust/typecheck/rust-hir-dot-operator.cc
@@ -123,86 +123,70 @@ MethodResolver::assemble_inherent_impl_candidates (
   bool receiver_is_raw_ptr = raw->get_kind () == TyTy::TypeKind::POINTER;
   bool receiver_is_ref = raw->get_kind () == TyTy::TypeKind::REF;
 
-  mappings.iterate_inherent_impl_blocks (
-    [&] (HirId, HIR::ImplBlock *impl) mutable -> bool {
-      for (auto &impl_item : impl->get_impl_items ())
-	{
-	  HIR::ImplItem *item = impl_item.get ();
-	  bool is_fn = item->get_impl_item_type ()
-		       == HIR::ImplItem::ImplItemType::FUNCTION;
-	  if (!is_fn)
-	    continue;
+  // Assemble inherent impl items (non-trait impl blocks).
+  mappings.iterate_inherent_impl_items (
+    segment_name.to_string (),
+    [&] (HIR::ImplItem *item, HIR::ImplBlock *impl) mutable -> bool {
+      HIR::Function *func = static_cast<HIR::Function *> (item);
 
-	  HIR::Function *func = static_cast<HIR::Function *> (item);
-	  if (!func->is_method ())
-	    continue;
+      TyTy::BaseType *impl_self = TypeCheckItem::ResolveImplBlockSelf (*impl);
 
-	  bool name_matches = func->get_function_name ().as_string ().compare (
-				segment_name.to_string ())
-			      == 0;
-	  if (!name_matches)
-	    continue;
-
-	  TyTy::BaseType *impl_self
-	    = TypeCheckItem::ResolveImplBlockSelf (*impl);
-
-	  if (impl_self == nullptr
-	      || impl_self->get_kind () == TyTy::TypeKind::ERROR)
-	    continue;
+      if (impl_self == nullptr
+	  || impl_self->get_kind () == TyTy::TypeKind::ERROR)
+	return true;
 
-	  if (receiver.get_kind () == TyTy::TypeKind::ADT
-	      && impl_self->get_kind () == TyTy::TypeKind::ADT)
-	    {
-	      const auto &receiver_adt
-		= static_cast<const TyTy::ADTType &> (receiver);
-	      const auto &impl_adt
-		= static_cast<const TyTy::ADTType &> (*impl_self);
-	      if (receiver_adt.get_id () != impl_adt.get_id ())
-		continue;
-	    }
+      if (receiver.get_kind () == TyTy::TypeKind::ADT
+	  && impl_self->get_kind () == TyTy::TypeKind::ADT)
+	{
+	  const auto &receiver_adt
+	    = static_cast<const TyTy::ADTType &> (receiver);
+	  const auto &impl_adt
+	    = static_cast<const TyTy::ADTType &> (*impl_self);
+	  if (receiver_adt.get_id () != impl_adt.get_id ())
+	    return true;
+	}
 
-	  // see:
-	  // https://gcc-rust.zulipchat.com/#narrow/stream/266897-general/topic/Method.20Resolution/near/338646280
-	  // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/method/probe.rs#L650-L660
-	  bool impl_self_is_ptr
-	    = impl_self->get_kind () == TyTy::TypeKind::POINTER;
-	  bool impl_self_is_ref = impl_self->get_kind () == TyTy::TypeKind::REF;
-	  if (receiver_is_raw_ptr && impl_self_is_ptr)
-	    {
-	      const TyTy::PointerType &sptr
-		= *static_cast<const TyTy::PointerType *> (impl_self);
-	      const TyTy::PointerType &ptr
-		= *static_cast<const TyTy::PointerType *> (raw);
-
-	      // we could do this via lang-item assemblies if we refactor this
-	      bool mut_match = sptr.mutability () == ptr.mutability ();
-	      if (!mut_match)
-		continue;
-	    }
-	  else if (receiver_is_ref && impl_self_is_ref)
-	    {
-	      const TyTy::ReferenceType &sptr
-		= *static_cast<const TyTy::ReferenceType *> (impl_self);
-	      const TyTy::ReferenceType &ptr
-		= *static_cast<const TyTy::ReferenceType *> (raw);
-
-	      // we could do this via lang-item assemblies if we refactor this
-	      bool mut_match = sptr.mutability () == ptr.mutability ();
-	      if (!mut_match)
-		continue;
-	    }
+      // see:
+      // https://gcc-rust.zulipchat.com/#narrow/stream/266897-general/topic/Method.20Resolution/near/338646280
+      // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/method/probe.rs#L650-L660
+      bool impl_self_is_ptr
+	= impl_self->get_kind () == TyTy::TypeKind::POINTER;
+      bool impl_self_is_ref = impl_self->get_kind () == TyTy::TypeKind::REF;
+      if (receiver_is_raw_ptr && impl_self_is_ptr)
+	{
+	  const TyTy::PointerType &sptr
+	    = *static_cast<const TyTy::PointerType *> (impl_self);
+	  const TyTy::PointerType &ptr
+	    = *static_cast<const TyTy::PointerType *> (raw);
+
+	  // we could do this via lang-item assemblies if we refactor this
+	  bool mut_match = sptr.mutability () == ptr.mutability ();
+	  if (!mut_match)
+	    return true;
+	}
+      else if (receiver_is_ref && impl_self_is_ref)
+	{
+	  const TyTy::ReferenceType &sptr
+	    = *static_cast<const TyTy::ReferenceType *> (impl_self);
+	  const TyTy::ReferenceType &ptr
+	    = *static_cast<const TyTy::ReferenceType *> (raw);
+
+	  // we could do this via lang-item assemblies if we refactor this
+	  bool mut_match = sptr.mutability () == ptr.mutability ();
+	  if (!mut_match)
+	    return true;
+	}
 
-	  TyTy::BaseType *ty = nullptr;
-	  if (!query_type (func->get_mappings ().get_hirid (), &ty))
-	    continue;
-	  if (ty == nullptr || ty->get_kind () == TyTy::TypeKind::ERROR)
-	    continue;
-	  if (ty->get_kind () != TyTy::TypeKind::FNDEF)
-	    continue;
+      TyTy::BaseType *ty = nullptr;
+      if (!query_type (func->get_mappings ().get_hirid (), &ty))
+	return true;
+      if (ty == nullptr || ty->get_kind () == TyTy::TypeKind::ERROR)
+	return true;
+      if (ty->get_kind () != TyTy::TypeKind::FNDEF)
+	return true;
 
-	  TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
-	  inherent_impl_fns.emplace_back (func, impl, fnty);
-	}
+      TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
+      inherent_impl_fns.emplace_back (func, impl, fnty);
       return true;
     });
 
@@ -333,7 +317,8 @@ MethodResolver::assemble_trait_impl_candidates (
   };
 
   if (specified_trait == nullptr)
-    mappings.iterate_trait_impl_blocks (process_impl);
+    mappings.iterate_trait_impl_blocks_for_item (segment_name.to_string (),
+						 process_impl);
   else
     mappings.iterate_trait_impl_blocks (
       specified_trait->get_mappings ().get_nodeid (), process_impl);
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 74496c00d..22cfba5ee 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -475,7 +475,21 @@ Mappings::insert_hir_impl_block (HIR::ImplBlock *item)
   if (item->has_trait_ref ())
     hirTraitImplBlockMappings[id] = item;
   else
-    hirInherentImplBlockMappings[id] = item;
+    {
+      for (auto &impl_item : item->get_impl_items ())
+	{
+	  if (impl_item->get_impl_item_type ()
+	      != HIR::ImplItem::ImplItemType::FUNCTION)
+	    continue;
+
+	  auto *function = static_cast<HIR::Function *> (impl_item.get ());
+	  if (!function->is_method ())
+	    continue;
+
+	  auto name = function->get_function_name ().as_string ();
+	  hirInherentImplItemMappings[name].emplace_back (impl_item.get (), item);
+	}
+    }
   hirImplBlockTypeMappings[impl_type_id] = item;
   insert_node_to_hir (item->get_mappings ().get_nodeid (), id);
 }
@@ -877,6 +891,49 @@ Mappings::insert_trait_impl_mapping (NodeId trait_node_id, HIR::ImplBlock *impl)
   hirTraitImplMappings[trait_node_id].push_back (impl);
 }
 
+void
+Mappings::iterate_trait_impl_blocks_for_item (
+  const std::string &name,
+  std::function<bool (HirId, HIR::ImplBlock *)> cb)
+{
+  auto traits = hirTraitItemNameMappings.find (name);
+  if (traits == hirTraitItemNameMappings.end ())
+    return;
+
+  for (auto trait_node_id : traits->second)
+    {
+      auto impls = hirTraitImplMappings.find (trait_node_id);
+      if (impls == hirTraitImplMappings.end ())
+	continue;
+
+      for (auto *impl : impls->second)
+	if (!cb (impl->get_mappings ().get_hirid (), impl))
+	  return;
+    }
+}
+
+void
+Mappings::insert_trait_item_mapping (HirId trait_item_id, HIR::Trait *trait)
+{
+  rust_assert (hirTraitItemsToTraitMappings.find (trait_item_id)
+	       == hirTraitItemsToTraitMappings.end ());
+  hirTraitItemsToTraitMappings[trait_item_id] = trait;
+
+  auto item = lookup_hir_trait_item (trait_item_id);
+  rust_assert (item.has_value ());
+  if (item.value ()->get_item_kind ()
+      != HIR::TraitItem::TraitItemKind::FUNC)
+    return;
+
+  auto *function = static_cast<HIR::TraitItemFunc *> (item.value ());
+  if (!function->get_decl ().is_method ())
+    return;
+
+  auto name = function->get_decl ().get_function_name ().as_string ();
+  hirTraitItemNameMappings[name].push_back (
+    trait->get_mappings ().get_nodeid ());
+}
+
 void
 Mappings::iterate_trait_impl_items (
   NodeId trait_node_id,
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index b30c412fa..4a2a1a8fb 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -208,6 +208,18 @@ public:
   void iterate_impl_items (
     std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb);
 
+  template <typename Callback>
+  void iterate_inherent_impl_items (const std::string &name, Callback &&cb)
+  {
+    auto items = hirInherentImplItemMappings.find (name);
+    if (items == hirInherentImplItemMappings.end ())
+      return;
+
+    for (auto &item : items->second)
+      if (!cb (item.first, item.second))
+	return;
+  }
+
   void insert_adt_impl_mapping (NodeId adt_node_id, HIR::ImplBlock *impl);
 
   void iterate_adt_impl_items (
@@ -232,13 +244,9 @@ public:
 	return;
   }
 
-  template <typename Callback> void iterate_inherent_impl_blocks (Callback &&cb)
-  {
-    for (auto it = hirInherentImplBlockMappings.begin ();
-	 it != hirInherentImplBlockMappings.end (); ++it)
-      if (!cb (it->first, it->second))
-	return;
-  }
+  void iterate_trait_impl_blocks_for_item (const std::string &name,
+					  std::function<bool (
+					    HirId, HIR::ImplBlock *)> cb);
 
   void iterate_impl_blocks (std::function<bool (HirId, HIR::ImplBlock *)> cb);
 
@@ -247,12 +255,7 @@ public:
 
   bool is_impl_item (HirId id) { return lookup_hir_implitem (id).has_value (); }
 
-  void insert_trait_item_mapping (HirId trait_item_id, HIR::Trait *trait)
-  {
-    rust_assert (hirTraitItemsToTraitMappings.find (trait_item_id)
-		 == hirTraitItemsToTraitMappings.end ());
-    hirTraitItemsToTraitMappings[trait_item_id] = trait;
-  }
+  void insert_trait_item_mapping (HirId trait_item_id, HIR::Trait *trait);
 
   HIR::Trait *lookup_trait_item_mapping (HirId trait_item_id)
   {
@@ -427,12 +430,15 @@ private:
   std::map<HirId, HIR::SelfParam *> hirSelfParamMappings;
   std::map<HirId, HIR::ImplBlock *> hirImplItemsToImplMappings;
   std::map<HirId, HIR::ImplBlock *> hirImplBlockMappings;
-  std::map<HirId, HIR::ImplBlock *> hirInherentImplBlockMappings;
   std::map<HirId, HIR::ImplBlock *> hirTraitImplBlockMappings;
+  std::map<std::string,
+	   std::vector<std::pair<HIR::ImplItem *, HIR::ImplBlock *>>>
+    hirInherentImplItemMappings;
   std::map<HirId, HIR::ImplBlock *> hirImplBlockTypeMappings;
   std::map<NodeId, std::vector<HIR::ImplBlock *>> hirAdtImplMappings;
   std::set<HIR::ImplBlock *> hirIndexedAdtImpls;
   std::map<NodeId, std::vector<HIR::ImplBlock *>> hirTraitImplMappings;
+  std::map<std::string, std::vector<NodeId>> hirTraitItemNameMappings;
   std::map<HirId, HIR::TraitItem *> hirTraitItemMappings;
   std::map<HirId, HIR::ExternBlock *> hirExternBlockMappings;
   std::map<HirId, std::pair<HIR::ExternalItem *, HirId>> hirExternItemMappings;
-- 
2.55.0



More information about the Gcc-rust mailing list