[gccrs COMMIT 4/5] gccrs: Add impl-item-name indexes for method resolution
gerris.rs@gmail.com
gerris.rs@gmail.com
Sun Sep 6 19:15:26 GMT 2026
From: Philip Herron <herron.philip@googlemail.com>
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 <herron.philip@googlemail.com>
---
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/a004d5ae4dba489341ca2330eb558bd504df5dbe
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/4847
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 a2ecb2649..a680a4aaa 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 74496c00d..22cfba5ee 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 b30c412fa..4a2a1a8fb 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;
--
2.55.0
More information about the Gcc-rust
mailing list