From: Philip Herron <herron.phi...@googlemail.com>

Refactor the dot operator implementation to improve code organization
and maintainability while preserving existing functionality.

gcc/rust/ChangeLog:

        * typecheck/rust-hir-dot-operator.cc: Major refactoring and cleanup.
        * typecheck/rust-hir-dot-operator.h: Add new helper methods.
---
 gcc/rust/typecheck/rust-hir-dot-operator.cc | 183 ++++++++++----------
 gcc/rust/typecheck/rust-hir-dot-operator.h  |  35 ++++
 2 files changed, 127 insertions(+), 91 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.cc 
b/gcc/rust/typecheck/rust-hir-dot-operator.cc
index c1165e9e5b1..7b7944c508d 100644
--- a/gcc/rust/typecheck/rust-hir-dot-operator.cc
+++ b/gcc/rust/typecheck/rust-hir-dot-operator.cc
@@ -102,26 +102,16 @@ MethodResolver::try_hook (const TyTy::BaseType &r)
     }
 }
 
-bool
-MethodResolver::select (TyTy::BaseType &receiver)
+std::vector<MethodResolver::impl_item_candidate>
+MethodResolver::assemble_inherent_impl_candidates (
+  const TyTy::BaseType &receiver)
 {
-  rust_debug ("MethodResolver::select reciever=[%s] path=[%s]",
-             receiver.debug_str ().c_str (),
-             segment_name.as_string ().c_str ());
-
-  struct impl_item_candidate
-  {
-    HIR::Function *item;
-    HIR::ImplBlock *impl_block;
-    TyTy::FnType *ty;
-  };
-
+  std::vector<impl_item_candidate> inherent_impl_fns;
   const TyTy::BaseType *raw = receiver.destructure ();
   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
-  std::vector<impl_item_candidate> inherent_impl_fns;
+  // 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 ();
@@ -190,16 +180,19 @@ MethodResolver::select (TyTy::BaseType &receiver)
       return true;
     });
 
-  struct trait_item_candidate
-  {
-    const HIR::TraitItemFunc *item;
-    const HIR::Trait *trait;
-    TyTy::FnType *ty;
-    const TraitReference *reference;
-    const TraitItemReference *item_ref;
-  };
+  return inherent_impl_fns;
+}
+
+void
+MethodResolver::assemble_trait_impl_candidates (
+  const TyTy::BaseType &receiver,
+  std::vector<impl_item_candidate> &impl_candidates,
+  std::vector<trait_item_candidate> &trait_candidates)
+{
+  const TyTy::BaseType *raw = receiver.destructure ();
+  bool receiver_is_raw_ptr = raw->get_kind () == TyTy::TypeKind::POINTER;
+  bool receiver_is_ref = raw->get_kind () == TyTy::TypeKind::REF;
 
-  std::vector<trait_item_candidate> trait_fns;
   mappings.iterate_impl_blocks ([&] (HirId id,
                                     HIR::ImplBlock *impl) mutable -> bool {
     bool is_trait_impl = impl->has_trait_ref ();
@@ -266,7 +259,7 @@ MethodResolver::select (TyTy::BaseType &receiver)
              continue;
          }
 
-       inherent_impl_fns.push_back ({func, impl, fnty});
+       impl_candidates.push_back ({func, impl, fnty});
        return true;
       }
 
@@ -293,26 +286,15 @@ MethodResolver::select (TyTy::BaseType &receiver)
     TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
 
     trait_item_candidate candidate{func, trait, fnty, trait_ref, item_ref};
-    trait_fns.push_back (candidate);
+    trait_candidates.push_back (candidate);
 
     return true;
   });
+}
 
-  // lookup specified bounds for an associated item
-  struct precdicate_candidate
-  {
-    TyTy::TypeBoundPredicateItem lookup;
-    TyTy::FnType *fntype;
-  };
-
-  // 
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}, "
-             "predicate_items found {%lu}",
-             (unsigned long) inherent_impl_fns.size (),
-             (unsigned long) trait_fns.size (),
-             (unsigned long) predicate_items.size ());
-
+bool
+MethodResolver::try_select_predicate_candidates (TyTy::BaseType &receiver)
+{
   bool found_possible_candidate = false;
   for (const auto &predicate : predicate_items)
     {
@@ -346,60 +328,33 @@ MethodResolver::select (TyTy::BaseType &receiver)
          found_possible_candidate = true;
        }
     }
-  if (found_possible_candidate)
-    {
-      return true;
-    }
+  return found_possible_candidate;
+}
 
-  for (auto &impl_item : inherent_impl_fns)
+bool
+MethodResolver::try_select_inherent_impl_candidates (
+  TyTy::BaseType &receiver, const std::vector<impl_item_candidate> &candidates,
+  bool trait_impl_blocks_only)
+{
+  bool found_possible_candidate = false;
+  for (auto &impl_item : candidates)
     {
       bool is_trait_impl_block = impl_item.impl_block->has_trait_ref ();
-      if (is_trait_impl_block)
+      if (trait_impl_blocks_only && !is_trait_impl_block)
        continue;
-
-      TyTy::FnType *fn = impl_item.ty;
-      rust_assert (fn->is_method ());
-
-      TyTy::BaseType *fn_self = fn->get_self_type ();
-      rust_debug ("dot-operator impl_item fn_self={%s} can_eq receiver={%s}",
-                 fn_self->debug_str ().c_str (),
-                 receiver.debug_str ().c_str ());
-
-      auto res
-       = TypeCoercionRules::TryCoerce (&receiver, fn_self, UNDEF_LOCATION,
-                                       false /*allow-autoderef*/);
-      bool ok = !res.is_error ();
-      if (ok)
-       {
-         std::vector<Adjustment> adjs = append_adjustments (res.adjustments);
-         PathProbeCandidate::ImplItemCandidate c{impl_item.item,
-                                                 impl_item.impl_block};
-         auto try_result = MethodCandidate{
-           PathProbeCandidate (PathProbeCandidate::CandidateType::IMPL_FUNC,
-                               fn, impl_item.item->get_locus (), c),
-           adjs};
-         result.insert (std::move (try_result));
-         found_possible_candidate = true;
-       }
-    }
-  if (found_possible_candidate)
-    {
-      return true;
-    }
-
-  for (auto &impl_item : inherent_impl_fns)
-    {
-      bool is_trait_impl_block = impl_item.impl_block->has_trait_ref ();
-      if (!is_trait_impl_block)
+      if (!trait_impl_blocks_only && is_trait_impl_block)
        continue;
 
       TyTy::FnType *fn = impl_item.ty;
       rust_assert (fn->is_method ());
 
       TyTy::BaseType *fn_self = fn->get_self_type ();
-      rust_debug (
-       "dot-operator trait_impl_item fn_self={%s} can_eq receiver={%s}",
-       fn_self->debug_str ().c_str (), receiver.debug_str ().c_str ());
+
+      const char *debug_prefix
+       = trait_impl_blocks_only ? "trait_impl_item" : "impl_item";
+      rust_debug ("dot-operator %s fn_self={%s} can_eq receiver={%s}",
+                 debug_prefix, fn_self->debug_str ().c_str (),
+                 receiver.debug_str ().c_str ());
 
       auto res
        = TypeCoercionRules::TryCoerce (&receiver, fn_self, UNDEF_LOCATION,
@@ -418,12 +373,15 @@ MethodResolver::select (TyTy::BaseType &receiver)
          found_possible_candidate = true;
        }
     }
-  if (found_possible_candidate)
-    {
-      return true;
-    }
+  return found_possible_candidate;
+}
 
-  for (auto trait_item : trait_fns)
+bool
+MethodResolver::try_select_trait_impl_candidates (
+  TyTy::BaseType &receiver, const std::vector<trait_item_candidate> 
&candidates)
+{
+  bool found_possible_candidate = false;
+  for (auto trait_item : candidates)
     {
       TyTy::FnType *fn = trait_item.ty;
       rust_assert (fn->is_method ());
@@ -451,10 +409,53 @@ MethodResolver::select (TyTy::BaseType &receiver)
          found_possible_candidate = true;
        }
     }
-
   return found_possible_candidate;
 }
 
+bool
+MethodResolver::select (TyTy::BaseType &receiver)
+{
+  rust_debug ("MethodResolver::select reciever=[%s] path=[%s]",
+             receiver.debug_str ().c_str (),
+             segment_name.as_string ().c_str ());
+
+  // Assemble candidates
+  std::vector<impl_item_candidate> inherent_impl_fns
+    = assemble_inherent_impl_candidates (receiver);
+  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}, "
+             "predicate_items found {%lu}",
+             (unsigned long) inherent_impl_fns.size (),
+             (unsigned long) trait_fns.size (),
+             (unsigned long) predicate_items.size ());
+
+  // Try selection in the priority order defined by Rust's method resolution:
+
+  // 1. Try predicate candidates first (highest priority)
+  if (try_select_predicate_candidates (receiver))
+    return true;
+
+  // 2. Try inherent impl functions (non-trait impl blocks)
+  if (try_select_inherent_impl_candidates (receiver, inherent_impl_fns, false))
+    return true;
+
+  // 3. Try inherent impl functions from trait impl blocks
+  if (try_select_inherent_impl_candidates (receiver, inherent_impl_fns, true))
+    return true;
+
+  // 4. Try trait functions (lowest priority)
+  return try_select_trait_impl_candidates (receiver, trait_fns);
+}
+
 std::vector<MethodResolver::predicate_candidate>
 MethodResolver::get_predicate_items (
   const HIR::PathIdentSegment &segment_name, const TyTy::BaseType &receiver,
diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.h 
b/gcc/rust/typecheck/rust-hir-dot-operator.h
index ab95a5a40c4..cc40472e0fa 100644
--- a/gcc/rust/typecheck/rust-hir-dot-operator.h
+++ b/gcc/rust/typecheck/rust-hir-dot-operator.h
@@ -65,6 +65,22 @@ public:
     const HIR::PathIdentSegment &segment_name, const TyTy::BaseType &receiver,
     const std::vector<TyTy::TypeBoundPredicate> &specified_bounds);
 
+  struct impl_item_candidate
+  {
+    HIR::Function *item;
+    HIR::ImplBlock *impl_block;
+    TyTy::FnType *ty;
+  };
+
+  struct trait_item_candidate
+  {
+    const HIR::TraitItemFunc *item;
+    const HIR::Trait *trait;
+    TyTy::FnType *ty;
+    const TraitReference *reference;
+    const TraitItemReference *item_ref;
+  };
+
 protected:
   MethodResolver (bool autoderef_flag,
                  const HIR::PathIdentSegment &segment_name);
@@ -77,6 +93,25 @@ private:
   std::vector<Adjustment>
   append_adjustments (const std::vector<Adjustment> &adjustments) const;
 
+  std::vector<impl_item_candidate>
+  assemble_inherent_impl_candidates (const TyTy::BaseType &receiver);
+
+  void assemble_trait_impl_candidates (
+    const TyTy::BaseType &receiver,
+    std::vector<impl_item_candidate> &impl_candidates,
+    std::vector<trait_item_candidate> &trait_candidates);
+
+  bool try_select_predicate_candidates (TyTy::BaseType &receiver);
+
+  bool try_select_inherent_impl_candidates (
+    TyTy::BaseType &receiver,
+    const std::vector<impl_item_candidate> &candidates,
+    bool trait_impl_blocks_only);
+
+  bool try_select_trait_impl_candidates (
+    TyTy::BaseType &receiver,
+    const std::vector<trait_item_candidate> &candidates);
+
 private:
   // search
   const HIR::PathIdentSegment &segment_name;
-- 
2.49.0

Reply via email to