[gccrs COMMIT 2/5] gccrs: Improve method resolution to use seperate indexes for impl's
gerris.rs@gmail.com
gerris.rs@gmail.com
Sun Sep 6 19:15:24 GMT 2026
From: Philip Herron <herron.philip@googlemail.com>
gcc/rust/ChangeLog:
* typecheck/rust-hir-dot-operator.cc (MethodResolver::select): use sperate index
* util/rust-hir-map.cc (Mappings::insert_hir_impl_block): new indexes
* 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/4d67061241ac10b7a38b12daaa2327cdcc7a42c1
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 | 169 ++++++++++----------
gcc/rust/util/rust-hir-map.cc | 4 +
gcc/rust/util/rust-hir-map.h | 18 +++
3 files changed, 106 insertions(+), 85 deletions(-)
diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.cc b/gcc/rust/typecheck/rust-hir-dot-operator.cc
index e42c4b90a..a2ecb2649 100644
--- a/gcc/rust/typecheck/rust-hir-dot-operator.cc
+++ b/gcc/rust/typecheck/rust-hir-dot-operator.cc
@@ -123,87 +123,88 @@ 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;
- // Assemble inherent impl items (non-trait impl blocks)
- mappings.iterate_impl_items ([&] (HirId id, HIR::ImplItem *item,
- HIR::ImplBlock *impl) mutable -> bool {
- bool is_trait_impl = impl->has_trait_ref ();
- if (is_trait_impl)
- return true;
+ 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;
- bool is_fn
- = item->get_impl_item_type () == HIR::ImplItem::ImplItemType::FUNCTION;
- if (!is_fn)
- return true;
+ HIR::Function *func = static_cast<HIR::Function *> (item);
+ if (!func->is_method ())
+ continue;
- HIR::Function *func = static_cast<HIR::Function *> (item);
- if (!func->is_method ())
- return true;
+ bool name_matches = func->get_function_name ().as_string ().compare (
+ segment_name.to_string ())
+ == 0;
+ if (!name_matches)
+ continue;
- bool name_matches = func->get_function_name ().as_string ().compare (
- segment_name.to_string ())
- == 0;
- if (!name_matches)
- return true;
+ TyTy::BaseType *impl_self
+ = TypeCheckItem::ResolveImplBlockSelf (*impl);
- 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)
+ TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
+ inherent_impl_fns.emplace_back (func, impl, fnty);
+ }
return true;
-
- TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
-
- inherent_impl_fns.emplace_back (func, impl, fnty);
-
- return true;
- });
+ });
return inherent_impl_fns;
}
@@ -332,7 +333,7 @@ MethodResolver::assemble_trait_impl_candidates (
};
if (specified_trait == nullptr)
- mappings.iterate_impl_blocks (process_impl);
+ mappings.iterate_trait_impl_blocks (process_impl);
else
mappings.iterate_trait_impl_blocks (
specified_trait->get_mappings ().get_nodeid (), process_impl);
@@ -484,15 +485,17 @@ MethodResolver::select (TyTy::BaseType &receiver)
// Assemble candidates
std::vector<impl_item_candidate> inherent_impl_fns;
if (specified_trait == nullptr)
- inherent_impl_fns = assemble_inherent_impl_candidates (receiver);
+ {
+ inherent_impl_fns = assemble_inherent_impl_candidates (receiver);
+ if (try_select_inherent_impl_candidates (receiver, inherent_impl_fns,
+ false))
+ return true;
+ }
+
std::vector<impl_item_candidate> trait_impl_fns;
std::vector<trait_item_candidate> trait_fns;
assemble_trait_impl_candidates (receiver, trait_impl_fns, trait_fns);
- // Combine inherent and trait impl functions
- inherent_impl_fns.insert (inherent_impl_fns.end (), trait_impl_fns.begin (),
- trait_impl_fns.end ());
-
// https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/method/probe.rs#L580-L694
rust_debug ("inherent_impl_fns found {%lu}, trait_fns found {%lu}, "
@@ -503,15 +506,11 @@ MethodResolver::select (TyTy::BaseType &receiver)
// Try selection in the priority order defined by Rust's method resolution:
- // 1. Try inherent impl functions (non-trait impl blocks)
- if (try_select_inherent_impl_candidates (receiver, inherent_impl_fns, false))
- return true;
-
- // 2. Try inherent impl functions from trait impl blocks
- if (try_select_inherent_impl_candidates (receiver, inherent_impl_fns, true))
+ // 1. Try inherent impl functions from trait impl blocks
+ if (try_select_inherent_impl_candidates (receiver, trait_impl_fns, true))
return true;
- // 3. Try trait functions (lowest priority)
+ // 2. Try trait functions (lowest priority)
return try_select_trait_impl_candidates (receiver, trait_fns);
}
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 3d8da522e..74496c00d 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -472,6 +472,10 @@ Mappings::insert_hir_impl_block (HIR::ImplBlock *item)
HirId impl_type_id = item->get_type ().get_mappings ().get_hirid ();
hirImplBlockMappings[id] = item;
+ if (item->has_trait_ref ())
+ hirTraitImplBlockMappings[id] = item;
+ else
+ hirInherentImplBlockMappings[id] = item;
hirImplBlockTypeMappings[impl_type_id] = item;
insert_node_to_hir (item->get_mappings ().get_nodeid (), id);
}
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 7595c49d6..b30c412fa 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -224,6 +224,22 @@ public:
iterate_trait_impl_blocks (NodeId trait_node_id,
std::function<bool (HirId, HIR::ImplBlock *)> cb);
+ template <typename Callback> void iterate_trait_impl_blocks (Callback &&cb)
+ {
+ for (auto it = hirTraitImplBlockMappings.begin ();
+ it != hirTraitImplBlockMappings.end (); ++it)
+ if (!cb (it->first, it->second))
+ 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_impl_blocks (std::function<bool (HirId, HIR::ImplBlock *)> cb);
void iterate_trait_items (
@@ -411,6 +427,8 @@ 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<HirId, HIR::ImplBlock *> hirImplBlockTypeMappings;
std::map<NodeId, std::vector<HIR::ImplBlock *>> hirAdtImplMappings;
std::set<HIR::ImplBlock *> hirIndexedAdtImpls;
--
2.55.0
More information about the Gcc-rust
mailing list