https://gcc.gnu.org/g:14ba81cbbee5aa02c4f7d9f9c21e18941677075a
commit r17-4299-g14ba81cbbee5aa02c4f7d9f9c21e18941677075a Author: Philip Herron <[email protected]> Date: Tue Aug 25 22:17:46 2026 +0100 gccrs: Register ADT mappings util helpers 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]> Diff: --- 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 19adb04a5ba6..f7cbcf1ac285 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 4245e8a38b9a..a6c378f25644 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 fc6a643077ef..87fca310e026 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 bfe04f0bc7a5..7595c49d6b09 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;
