https://gcc.gnu.org/g:6e2b28a550307e7cfb4b4d9a60cdb4e760c9fdff
commit r17-4292-g6e2b28a550307e7cfb4b4d9a60cdb4e760c9fdff Author: Philip Herron <[email protected]> Date: Sun Aug 23 20:01:00 2026 +0100 gccrs: Add indexing ImplTrait Blocks to Trait map for improved filtering This is just a general improvement so we can filter trait probing to not look at the whole crate. gcc/rust/ChangeLog: * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): add mapping * rust-session-manager.cc (Session::compile_crate): make sure nr context is ready * typecheck/rust-hir-path-probe.cc (PathProbeImplTrait::process_trait_impl_items_for_candidates): use the new filter * util/rust-hir-map.cc (Mappings::insert_trait_impl_mapping): new helper * util/rust-hir-map.h: likewise Signed-off-by: Philip Herron <[email protected]> Diff: --- gcc/rust/hir/rust-ast-lower-item.cc | 8 ++++++++ gcc/rust/rust-session-manager.cc | 7 ++++--- gcc/rust/typecheck/rust-hir-path-probe.cc | 13 +++---------- gcc/rust/util/rust-hir-map.cc | 25 +++++++++++++++++++++++++ gcc/rust/util/rust-hir-map.h | 7 +++++++ 5 files changed, 47 insertions(+), 13 deletions(-) diff --git a/gcc/rust/hir/rust-ast-lower-item.cc b/gcc/rust/hir/rust-ast-lower-item.cc index 84ed9c90d3ca..19adb04a5ba6 100644 --- a/gcc/rust/hir/rust-ast-lower-item.cc +++ b/gcc/rust/hir/rust-ast-lower-item.cc @@ -27,6 +27,7 @@ #include "rust-ast-lower-pattern.h" #include "rust-ast-lower-block.h" #include "rust-item.h" +#include "rust-finalized-name-resolution-context.h" namespace Rust { namespace HIR { @@ -765,6 +766,13 @@ ASTLoweringItem::visit (AST::TraitImpl &impl_block) translated = hir_impl_block; mappings.insert_hir_impl_block (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); + rust_assert (trait_node_id.has_value ()); + mappings.insert_trait_impl_mapping (trait_node_id.value (), hir_impl_block); + for (auto &impl_item_id : impl_item_ids) { mappings.insert_impl_item_mapping (impl_item_id, hir_impl_block); diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index f6fabb3bff58..29b12bb13b84 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -780,6 +780,10 @@ Session::compile_crate (const char *filename) if (last_step == CompileOptions::CompileStep::Lowering) return; + // Name resolution is complete. Freeze its context before lowering so HIR + // construction can register information keyed by resolved definitions. + Resolver2_0::FinalizedNameResolutionContext::init (name_resolution_ctx); + // lower AST to HIR std::unique_ptr<HIR::Crate> lowered = HIR::ASTLowering::Resolve (parsed_crate); @@ -800,9 +804,6 @@ Session::compile_crate (const char *filename) if (last_step == CompileOptions::CompileStep::TypeCheck) return; - // name resolution is done, we now freeze the name resolver for type checking - Resolver2_0::FinalizedNameResolutionContext::init (name_resolution_ctx); - // type resolve Compile::Context *ctx = Compile::Context::get (); Resolver::TypeResolution::Resolve (hir); diff --git a/gcc/rust/typecheck/rust-hir-path-probe.cc b/gcc/rust/typecheck/rust-hir-path-probe.cc index 4c37762b6925..d8ff6ff62c2c 100644 --- a/gcc/rust/typecheck/rust-hir-path-probe.cc +++ b/gcc/rust/typecheck/rust-hir-path-probe.cc @@ -464,17 +464,10 @@ PathProbeImplTrait::Probe (TyTy::BaseType *receiver, void PathProbeImplTrait::process_trait_impl_items_for_candidates () { - mappings.iterate_impl_items ( + NodeId trait_node_id = trait_reference->get_mappings ().get_nodeid (); + mappings.iterate_trait_impl_items ( + trait_node_id, [&] (HirId id, HIR::ImplItem *item, HIR::ImplBlock *impl) mutable -> bool { - // just need to check if this is an impl block for this trait the next - // function checks the receiver - if (!impl->has_trait_ref ()) - return true; - - TraitReference *resolved = TraitResolver::Lookup (impl->get_trait_ref ()); - if (!trait_reference->is_equal (*resolved)) - return true; - process_impl_item_candidate (id, item, impl); return true; }); diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc index 58427b98631d..d7d0cc87c2a1 100644 --- a/gcc/rust/util/rust-hir-map.cc +++ b/gcc/rust/util/rust-hir-map.cc @@ -829,6 +829,31 @@ Mappings::iterate_impl_items ( } } +void +Mappings::insert_trait_impl_mapping (NodeId trait_node_id, HIR::ImplBlock *impl) +{ + hirTraitImplMappings[trait_node_id].push_back (impl); +} + +void +Mappings::iterate_trait_impl_items ( + NodeId trait_node_id, + std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb) +{ + auto trait_impls = hirTraitImplMappings.find (trait_node_id); + if (trait_impls == hirTraitImplMappings.end ()) + return; + + for (auto *impl : trait_impls->second) + 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; + } +} + void Mappings::iterate_impl_blocks (std::function<bool (HirId, HIR::ImplBlock *)> cb) { diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h index dfbec3c88a70..2f7431a00c88 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_trait_impl_mapping (NodeId trait_node_id, HIR::ImplBlock *impl); + + void iterate_trait_impl_items ( + NodeId trait_node_id, + std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb); + void iterate_impl_blocks (std::function<bool (HirId, HIR::ImplBlock *)> cb); void iterate_trait_items ( @@ -396,6 +402,7 @@ 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 *>> hirTraitImplMappings; std::map<HirId, HIR::TraitItem *> hirTraitItemMappings; std::map<HirId, HIR::ExternBlock *> hirExternBlockMappings; std::map<HirId, std::pair<HIR::ExternalItem *, HirId>> hirExternItemMappings;
