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