From: Philip Herron <[email protected]>

This is just a general improvement so we can filter trait probing to not
look at the whole crate.

gcc/rust/ChangeLog:

        * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): add mapping
        * rust-session-manager.cc (Session::compile_crate): make sure nr 
context is ready
        * typecheck/rust-hir-path-probe.cc
        (PathProbeImplTrait::process_trait_impl_items_for_candidates): use the 
new filter
        * util/rust-hir-map.cc (Mappings::insert_trait_impl_mapping): new 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/3f55ce04e23c558010ed5a128350dd0a26d896f7

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       |  8 ++++++++
 gcc/rust/rust-session-manager.cc          |  7 ++++---
 gcc/rust/typecheck/rust-hir-path-probe.cc | 13 +++---------
 gcc/rust/util/rust-hir-map.cc             | 25 +++++++++++++++++++++++
 gcc/rust/util/rust-hir-map.h              |  7 +++++++
 5 files changed, 47 insertions(+), 13 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-item.cc 
b/gcc/rust/hir/rust-ast-lower-item.cc
index 84ed9c90d..19adb04a5 100644
--- a/gcc/rust/hir/rust-ast-lower-item.cc
+++ b/gcc/rust/hir/rust-ast-lower-item.cc
@@ -27,6 +27,7 @@
 #include "rust-ast-lower-pattern.h"
 #include "rust-ast-lower-block.h"
 #include "rust-item.h"
+#include "rust-finalized-name-resolution-context.h"
 
 namespace Rust {
 namespace HIR {
@@ -765,6 +766,13 @@ ASTLoweringItem::visit (AST::TraitImpl &impl_block)
   translated = hir_impl_block;
 
   mappings.insert_hir_impl_block (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);
+  rust_assert (trait_node_id.has_value ());
+  mappings.insert_trait_impl_mapping (trait_node_id.value (), hir_impl_block);
+
   for (auto &impl_item_id : impl_item_ids)
     {
       mappings.insert_impl_item_mapping (impl_item_id, hir_impl_block);
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index f6fabb3bf..29b12bb13 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -780,6 +780,10 @@ Session::compile_crate (const char *filename)
   if (last_step == CompileOptions::CompileStep::Lowering)
     return;
 
+  // Name resolution is complete.  Freeze its context before lowering so HIR
+  // construction can register information keyed by resolved definitions.
+  Resolver2_0::FinalizedNameResolutionContext::init (name_resolution_ctx);
+
   // lower AST to HIR
   std::unique_ptr<HIR::Crate> lowered
     = HIR::ASTLowering::Resolve (parsed_crate);
@@ -800,9 +804,6 @@ Session::compile_crate (const char *filename)
   if (last_step == CompileOptions::CompileStep::TypeCheck)
     return;
 
-  // name resolution is done, we now freeze the name resolver for type checking
-  Resolver2_0::FinalizedNameResolutionContext::init (name_resolution_ctx);
-
   // type resolve
   Compile::Context *ctx = Compile::Context::get ();
   Resolver::TypeResolution::Resolve (hir);
diff --git a/gcc/rust/typecheck/rust-hir-path-probe.cc 
b/gcc/rust/typecheck/rust-hir-path-probe.cc
index 4c37762b6..d8ff6ff62 100644
--- a/gcc/rust/typecheck/rust-hir-path-probe.cc
+++ b/gcc/rust/typecheck/rust-hir-path-probe.cc
@@ -464,17 +464,10 @@ PathProbeImplTrait::Probe (TyTy::BaseType *receiver,
 void
 PathProbeImplTrait::process_trait_impl_items_for_candidates ()
 {
-  mappings.iterate_impl_items (
+  NodeId trait_node_id = trait_reference->get_mappings ().get_nodeid ();
+  mappings.iterate_trait_impl_items (
+    trait_node_id,
     [&] (HirId id, HIR::ImplItem *item, HIR::ImplBlock *impl) mutable -> bool {
-      // just need to check if this is an impl block for this trait the next
-      // function checks the receiver
-      if (!impl->has_trait_ref ())
-       return true;
-
-      TraitReference *resolved = TraitResolver::Lookup (impl->get_trait_ref 
());
-      if (!trait_reference->is_equal (*resolved))
-       return true;
-
       process_impl_item_candidate (id, item, impl);
       return true;
     });
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 58427b986..d7d0cc87c 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -829,6 +829,31 @@ Mappings::iterate_impl_items (
     }
 }
 
+void
+Mappings::insert_trait_impl_mapping (NodeId trait_node_id, HIR::ImplBlock 
*impl)
+{
+  hirTraitImplMappings[trait_node_id].push_back (impl);
+}
+
+void
+Mappings::iterate_trait_impl_items (
+  NodeId trait_node_id,
+  std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb)
+{
+  auto trait_impls = hirTraitImplMappings.find (trait_node_id);
+  if (trait_impls == hirTraitImplMappings.end ())
+    return;
+
+  for (auto *impl : trait_impls->second)
+    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;
+      }
+}
+
 void
 Mappings::iterate_impl_blocks (std::function<bool (HirId, HIR::ImplBlock *)> 
cb)
 {
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index dfbec3c88..2f7431a00 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_trait_impl_mapping (NodeId trait_node_id, HIR::ImplBlock *impl);
+
+  void iterate_trait_impl_items (
+    NodeId trait_node_id,
+    std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb);
+
   void iterate_impl_blocks (std::function<bool (HirId, HIR::ImplBlock *)> cb);
 
   void iterate_trait_items (
@@ -396,6 +402,7 @@ 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 *>> hirTraitImplMappings;
   std::map<HirId, HIR::TraitItem *> hirTraitItemMappings;
   std::map<HirId, HIR::ExternBlock *> hirExternBlockMappings;
   std::map<HirId, std::pair<HIR::ExternalItem *, HirId>> hirExternItemMappings;
-- 
2.55.0

Reply via email to