https://gcc.gnu.org/g:9917d9e60cbe9346c4eba5e5dc653c57f79d9c7e
commit r17-4333-g9917d9e60cbe9346c4eba5e5dc653c57f79d9c7e Author: Philip Herron <[email protected]> Date: Fri Sep 4 21:33:43 2026 +0100 gccrs: Add impl-item-name indexes for method resolution 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 <[email protected]> Diff: --- 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 a2ecb26498a1..a680a4aaaf99 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 74496c00d144..22cfba5eea3d 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 b30c412fa681..4a2a1a8fbad4 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;
