https://gcc.gnu.org/g:29e6cfbd27776087073f3f0d8295c5598a893d36

commit r16-2884-g29e6cfbd27776087073f3f0d8295c5598a893d36
Author: Philip Herron <herron.phi...@googlemail.com>
Date:   Fri Jun 20 17:49:32 2025 +0100

    gccrs: Ensure we look at the bounds behind a reference
    
    When type checking expressions that involve references, we need to
    examine the bounds of the referenced type to properly resolve traits
    and methods.
    
    gcc/rust/ChangeLog:
    
            * typecheck/rust-hir-type-check-expr.cc: Look at bounds behind
            references.
            * typecheck/rust-hir-type-check-expr.h: Add helper method.

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-expr.cc | 37 +++++++++++++++++++++-----
 gcc/rust/typecheck/rust-hir-type-check-expr.h  |  3 ++-
 2 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 81d95c83239f..753d3915f69f 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -2086,16 +2086,13 @@ TypeCheckExpr::resolve_operator_overload (
 
 HIR::PathIdentSegment
 TypeCheckExpr::resolve_possible_fn_trait_call_method_name (
-  TyTy::BaseType &receiver, TyTy::TypeBoundPredicate *associated_predicate)
+  const TyTy::BaseType &receiver,
+  TyTy::TypeBoundPredicate *associated_predicate)
 {
-  // Question
-  // do we need to probe possible bounds here? I think not, i think when we
-  // support Fn traits they are explicitly specified
-
   // FIXME
   // the logic to map the FnTrait to their respective call trait-item is
   // duplicated over in the backend/rust-compile-expr.cc
-  for (auto &bound : receiver.get_specified_bounds ())
+  for (const auto &bound : receiver.get_specified_bounds ())
     {
       bool found_fn = bound.get_name ().compare ("Fn") == 0;
       bool found_fn_mut = bound.get_name ().compare ("FnMut") == 0;
@@ -2118,6 +2115,34 @@ 
TypeCheckExpr::resolve_possible_fn_trait_call_method_name (
        }
     }
 
+  if (receiver.is<TyTy::ReferenceType> ())
+    {
+      const auto &ref = static_cast<const TyTy::ReferenceType &> (receiver);
+      const auto &underlying = *ref.get_base ();
+      for (const auto &bound : underlying.get_specified_bounds ())
+       {
+         bool found_fn = bound.get_name ().compare ("Fn") == 0;
+         bool found_fn_mut = bound.get_name ().compare ("FnMut") == 0;
+         bool found_fn_once = bound.get_name ().compare ("FnOnce") == 0;
+
+         if (found_fn)
+           {
+             *associated_predicate = bound;
+             return HIR::PathIdentSegment ("call");
+           }
+         else if (found_fn_mut)
+           {
+             *associated_predicate = bound;
+             return HIR::PathIdentSegment ("call_mut");
+           }
+         else if (found_fn_once)
+           {
+             *associated_predicate = bound;
+             return HIR::PathIdentSegment ("call_once");
+           }
+       }
+    }
+
   // nothing
   *associated_predicate = TyTy::TypeBoundPredicate::error ();
   return HIR::PathIdentSegment ("");
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h 
b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index e0a3278fb82d..531197436853 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -109,7 +109,8 @@ protected:
                              TyTy::BaseType **result);
 
   HIR::PathIdentSegment resolve_possible_fn_trait_call_method_name (
-    TyTy::BaseType &receiver, TyTy::TypeBoundPredicate *associated_predicate);
+    const TyTy::BaseType &receiver,
+    TyTy::TypeBoundPredicate *associated_predicate);
 
 private:
   TypeCheckExpr ();

Reply via email to