From: Philip Herron <[email protected]>

gcc/rust/ChangeLog:

        * hir/rust-ast-lower-item.cc (register_adt_impl): new mappings
        (ASTLoweringItem::visit): tracker function
        * typecheck/rust-hir-path-probe.cc 
(PathProbeType::process_impl_items_for_candidates):
        iterator
        * util/rust-hir-map.cc (Mappings::insert_adt_impl_mapping): helper
        * util/rust-hir-map.h: likewise

Signed-off-by: Philip Herron <[email protected]>
---
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/09d8ef22369a000ea3c232d89c93e63413a51447

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/4816

 gcc/rust/hir/rust-ast-lower-item.cc       | 23 +++++++++++++
 gcc/rust/typecheck/rust-hir-path-probe.cc | 17 ++++++++++
 gcc/rust/util/rust-hir-map.cc             | 41 +++++++++++++++++++++++
 gcc/rust/util/rust-hir-map.h              |  8 +++++
 4 files changed, 89 insertions(+)

diff --git a/gcc/rust/hir/rust-ast-lower-item.cc 
b/gcc/rust/hir/rust-ast-lower-item.cc
index 19adb04a5..f7cbcf1ac 100644
--- a/gcc/rust/hir/rust-ast-lower-item.cc
+++ b/gcc/rust/hir/rust-ast-lower-item.cc
@@ -32,6 +32,26 @@
 namespace Rust {
 namespace HIR {
 
+static void
+register_adt_impl (Analysis::Mappings &mappings, HIR::Type *impl_type,
+                  HIR::ImplBlock *impl)
+{
+  auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
+  auto resolved = nr_ctx.lookup (impl_type->get_mappings ().get_nodeid (),
+                                Resolver2_0::Namespace::Types);
+  if (!resolved.has_value ())
+    return;
+
+  auto ast_item = mappings.lookup_ast_item (resolved.value ());
+  if (!ast_item.has_value ())
+    return;
+
+  auto kind = ast_item.value ()->get_item_kind ();
+  if (kind == AST::Item::Kind::Struct || kind == AST::Item::Kind::Enum
+      || kind == AST::Item::Kind::Union)
+    mappings.insert_adt_impl_mapping (resolved.value (), impl);
+}
+
 HIR::Item *
 ASTLoweringItem::translate (AST::Item &item)
 {
@@ -594,6 +614,7 @@ ASTLoweringItem::visit (AST::InherentImpl &impl_block)
   translated = hir_impl_block;
 
   mappings.insert_hir_impl_block (hir_impl_block);
+  register_adt_impl (mappings, impl_type, hir_impl_block);
   for (auto &impl_item_id : impl_item_ids)
     {
       mappings.insert_impl_item_mapping (impl_item_id, hir_impl_block);
@@ -767,6 +788,8 @@ ASTLoweringItem::visit (AST::TraitImpl &impl_block)
 
   mappings.insert_hir_impl_block (hir_impl_block);
 
+  register_adt_impl (mappings, impl_type, hir_impl_block);
+
   auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
   auto trait_node_id = nr_ctx.lookup (trait_ref->get_mappings ().get_nodeid (),
                                      Resolver2_0::Namespace::Types);
diff --git a/gcc/rust/typecheck/rust-hir-path-probe.cc 
b/gcc/rust/typecheck/rust-hir-path-probe.cc
index 4245e8a38..a6c378f25 100644
--- a/gcc/rust/typecheck/rust-hir-path-probe.cc
+++ b/gcc/rust/typecheck/rust-hir-path-probe.cc
@@ -300,6 +300,23 @@ PathProbeType::process_enum_item_for_candiates (const 
TyTy::ADTType *adt)
 void
 PathProbeType::process_impl_items_for_candidates ()
 {
+  if (auto *adt = receiver->try_as<TyTy::ADTType> ())
+    {
+      auto adt_item = mappings.lookup_defid (adt->get_id ());
+      if (adt_item.has_value ())
+       {
+         NodeId adt_node_id = adt_item.value ()->get_mappings ().get_nodeid ();
+         mappings.iterate_adt_impl_items (
+           adt_node_id,
+           [&] (HirId id, HIR::ImplItem *item,
+                HIR::ImplBlock *impl) mutable -> bool {
+             process_impl_item_candidate (id, item, impl);
+             return true;
+           });
+         return;
+       }
+    }
+
   mappings.iterate_impl_items (
     [&] (HirId id, HIR::ImplItem *item, HIR::ImplBlock *impl) mutable -> bool {
       process_impl_item_candidate (id, item, impl);
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index fc6a64307..87fca310e 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -829,6 +829,47 @@ Mappings::iterate_impl_items (
     }
 }
 
+void
+Mappings::insert_adt_impl_mapping (NodeId adt_node_id, HIR::ImplBlock *impl)
+{
+  hirAdtImplMappings[adt_node_id].push_back (impl);
+  hirIndexedAdtImpls.insert (impl);
+}
+
+void
+Mappings::iterate_adt_impl_items (
+  NodeId adt_node_id,
+  std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb)
+{
+  auto iterate_impl = [&] (HIR::ImplBlock *impl) {
+    for (auto &item : impl->get_impl_items ())
+      {
+       HIR::ImplItem *impl_item = item.get ();
+       HirId id = impl_item->get_impl_mappings ().get_hirid ();
+       if (!cb (id, impl_item, impl))
+         return false;
+      }
+    return true;
+  };
+
+  auto adt_impls = hirAdtImplMappings.find (adt_node_id);
+  if (adt_impls != hirAdtImplMappings.end ())
+    for (auto *impl : adt_impls->second)
+      if (!iterate_impl (impl))
+       return;
+
+  // Impl self types which cannot be classified as a concrete ADT include
+  // blanket implementations such as `impl<T> Trait for T`.  They must remain
+  // candidates for every ADT receiver.
+  for (auto &mapping : hirImplBlockMappings)
+    {
+      HIR::ImplBlock *impl = mapping.second;
+      if (hirIndexedAdtImpls.find (impl) == hirIndexedAdtImpls.end ())
+       if (!iterate_impl (impl))
+         return;
+    }
+}
+
 void
 Mappings::insert_trait_impl_mapping (NodeId trait_node_id, HIR::ImplBlock 
*impl)
 {
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index bfe04f0bc..7595c49d6 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -208,6 +208,12 @@ public:
   void iterate_impl_items (
     std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb);
 
+  void insert_adt_impl_mapping (NodeId adt_node_id, HIR::ImplBlock *impl);
+
+  void iterate_adt_impl_items (
+    NodeId adt_node_id,
+    std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb);
+
   void insert_trait_impl_mapping (NodeId trait_node_id, HIR::ImplBlock *impl);
 
   void iterate_trait_impl_items (
@@ -406,6 +412,8 @@ private:
   std::map<HirId, HIR::ImplBlock *> hirImplItemsToImplMappings;
   std::map<HirId, HIR::ImplBlock *> hirImplBlockMappings;
   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<HirId, HIR::TraitItem *> hirTraitItemMappings;
   std::map<HirId, HIR::ExternBlock *> hirExternBlockMappings;
-- 
2.55.0

Reply via email to